Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-30 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 First off, I agree that verify-tag is probably not the right place.
 There _is_ no tag object to verify anymore (the only reason it is a tag
 at all is that the signature came out of what once was a tag).

Yes, if we imagine that the header were called mergesig, it may be
more apparent what it is.  Similar to the commit signature itself
(which gives GPG protection over the commit itself), a mergesig
covers one of the parent commit object name recorded in the commit.

You could look at it as one aspect of the child commit object being
verified, and that is why I would suggest it is the responsibility
of verify-commit that is run on the child commit (I saw suggestions
to verify other aspects such as author ident matches the GPG signer
of the signature on the commit itself, etc.)

 Let us imagine that we have a verify-commit that verifies commit
 signatures made by commit -S. If I run verify-commit foo, that
 implies to me two things:

   1. I am verifying the signature over the contents of foo.

  But the mergetag is _not_ a statement about foo; the person who
  signed it never saw foo. It is a statement about foo^2 at best,
  or possibly about the whole history of foo^1..foo^2.

   2. I am verifying _only_ the contents of foo. That is, I expect people
  to use commit -S to cryptographically claim authorship of a
  commit. Whereas with tags, I think we have typically taken them to
  mean I have signed the tip of a segment of history, and I am
  taking responsibility for the final state (e.g., signing release
  tags).

I think you are making it too hard ;-).  Fundamentally, a signature
on a commit object itself _can_ be used to attest _some_ property
about the whole history behind it by the signer, but it does not
prevent a project from adopting a lot looser convention.  If a
project's stance is commit signature in this project is about the
contents of the tree (i.e. the signer does not have much confidence
in his memory on how he got there), the result from verify-commit on
the signature of the commit itself should be interpreted in the
context of such a project as such---the signer is confident that the
tree matches what he signed and the signature wouldn't mean any more
than that.

  I realize that this claim is somewhat tenuous. It's not something
  inherent in the crypto, but rather in the social convention of what
  it means to sign a commit.

Yup, I think we are on the same page.

  But I would ask, then: what
  is the point of signing a commit versus signing a tag?  I think
  that people who wanted commit signatures wanted them to give a
  stronger guarantee of authorship of individual commits.

There are practical concerns.

 - tags are easier to manage because you can make a commit, give it
   out for trials by guinea pigs and then after it proves good, you
   can add a signed tag after the fact without rewriting the commit
   itself.  Incidentally, this is the primary reason behind the
   design of mergetags that were introduced after the k.org break-in
   fiasco.

   Theoretically you could have argued that lieutenants can sign the
   commits they want Linus to pull and we wouldn't have had to add
   anything to the system to support the new not only we can use
   third-party publishing sites that we do not know how much we can
   trust, such as GitHub, we do not even have to trust k.org blindly
   workflow.  But they really wanted to be able to commit first,
   let time pass and then sign to request pulling.

 - tags are a lot more cumbersome if you want to sign each and every
   commit (which some of us view as pointless, given the chain of
   SHA-1 hashes our history storage is based on), because you end up
   having to name, keep and transfer O(n) refs to represent them for
   the history of project of size n.  Embedding signature in each
   commit would be the only workable way if somebody wants to sign
   each and every commit.

  Git has largely stayed agnostic about what such signatures mean.
  But if we accept that some projects _are_ going to make that
  distinction, I think conflating verification of the two within the
  same command leads to a potential for confusion.

I agree that the users and scripts must be able to inspect the
validity of gpgsig and mergetag(s) separately.  When you inspect
a merge commit, if gpgsig verifies but mergetag does not, we know
that the integrator created and signed the merge but we do not know
if the lieutenant whose name appears on the mergetag really asked
the side branch to be pulled, or if the merge was made in response
to a request by an imposter.  For that matter, when verifying an
octopus merge, we must be able to see the validity of mergetag for
each parent separately.  We can do that by having two separate
commands (one to verify gpgsig, the other to verify mergetag),
or we can do that with a separate command line options to a single

Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-27 Thread Michael J Gruber
Jeff King venit, vidit, dixit 16.06.2014 22:39:
 On Mon, Jun 16, 2014 at 01:34:20PM -0700, Junio C Hamano wrote:
 
 Your middle example above did make me think of one other thing, though.
 As you noted, we actually have _three_ signature types:

   1. signed tags

   2. signed commits

   3. merges with embedded mergetag headers

 We already have a tool for (1). Michael is adding a tool for (2). How
 would one check (3) in a similar way?

 Hmph, somehow I misread the patch that it was for both 2  3 X-.
 
 I was just assuming it handles only (2) without checking further, so I
 may be wrong. But I do not think it makes sense to conflate (2) and (3).
 A merge commit may have both, and they are separate signatures.
 
 For that matter, is there a way to expose (3) currently, besides via
 --show-signature? It does not trigger %GG and friends (nor should it).
 It may make sense to add extra format specifiers for mergetag
 signatures. Though I do not use them myself, so I am not clear on what
 the use case is besides a manual, human verification of a particular
 merge.

I'm afraid I'm on a weekly git schedule at best, sorry. Just trying to
catch up on this:

Admittedly, I simply don't know about 3.. I know only 1. and 2. (and
don't remember why they are implemented differently).

Are they documented/decribed somewhere?

Meanwhile, I'm rebasing on top of the %G related patches by Junio and
Jeff and hope to send out a v4 later today.

Michael
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-27 Thread Michael J Gruber
Michael J Gruber venit, vidit, dixit 27.06.2014 14:31:
 Jeff King venit, vidit, dixit 16.06.2014 22:39:
 On Mon, Jun 16, 2014 at 01:34:20PM -0700, Junio C Hamano wrote:

 Your middle example above did make me think of one other thing, though.
 As you noted, we actually have _three_ signature types:

   1. signed tags

   2. signed commits

   3. merges with embedded mergetag headers

 We already have a tool for (1). Michael is adding a tool for (2). How
 would one check (3) in a similar way?

 Hmph, somehow I misread the patch that it was for both 2  3 X-.

 I was just assuming it handles only (2) without checking further, so I
 may be wrong. But I do not think it makes sense to conflate (2) and (3).
 A merge commit may have both, and they are separate signatures.

 For that matter, is there a way to expose (3) currently, besides via
 --show-signature? It does not trigger %GG and friends (nor should it).
 It may make sense to add extra format specifiers for mergetag
 signatures. Though I do not use them myself, so I am not clear on what
 the use case is besides a manual, human verification of a particular
 merge.
 
 I'm afraid I'm on a weekly git schedule at best, sorry. Just trying to
 catch up on this:
 
 Admittedly, I simply don't know about 3.. I know only 1. and 2. (and
 don't remember why they are implemented differently).
 
 Are they documented/decribed somewhere?
 
 Meanwhile, I'm rebasing on top of the %G related patches by Junio and
 Jeff and hope to send out a v4 later today.
 
 Michael

OK, found the two commits which git log -Smergetag outputs, but no tests.

A merge commit with embedded signed tag it is, then.

The commit could carry it's own commit signature, couldn't it?
That would suggest that we use git verify-tag to verify the embedded
signed tag of a merge commit and git verify-commit to verify the
commit signature.

OTOH I would like these basic commands to be as strict as possible,
including type-checks. Does that mean having git verify-mergetag which
verifies that it is being used on a merge commit with embedded mergetag?

(BTW: Is there anything keeping a non-merge commit from having an
embedded (merge) tag?)

Michael
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-27 Thread Michael J Gruber
Michael J Gruber venit, vidit, dixit 27.06.2014 14:49:
 Michael J Gruber venit, vidit, dixit 27.06.2014 14:31:
 Jeff King venit, vidit, dixit 16.06.2014 22:39:
 On Mon, Jun 16, 2014 at 01:34:20PM -0700, Junio C Hamano wrote:

 Your middle example above did make me think of one other thing, though.
 As you noted, we actually have _three_ signature types:

   1. signed tags

   2. signed commits

   3. merges with embedded mergetag headers

 We already have a tool for (1). Michael is adding a tool for (2). How
 would one check (3) in a similar way?

 Hmph, somehow I misread the patch that it was for both 2  3 X-.

 I was just assuming it handles only (2) without checking further, so I
 may be wrong. But I do not think it makes sense to conflate (2) and (3).
 A merge commit may have both, and they are separate signatures.

 For that matter, is there a way to expose (3) currently, besides via
 --show-signature? It does not trigger %GG and friends (nor should it).
 It may make sense to add extra format specifiers for mergetag
 signatures. Though I do not use them myself, so I am not clear on what
 the use case is besides a manual, human verification of a particular
 merge.

 I'm afraid I'm on a weekly git schedule at best, sorry. Just trying to
 catch up on this:

 Admittedly, I simply don't know about 3.. I know only 1. and 2. (and
 don't remember why they are implemented differently).

 Are they documented/decribed somewhere?

 Meanwhile, I'm rebasing on top of the %G related patches by Junio and
 Jeff and hope to send out a v4 later today.

 Michael
 
 OK, found the two commits which git log -Smergetag outputs, but no tests.
 
 A merge commit with embedded signed tag it is, then.
 
 The commit could carry it's own commit signature, couldn't it?
 That would suggest that we use git verify-tag to verify the embedded
 signed tag of a merge commit and git verify-commit to verify the
 commit signature.
 
 OTOH I would like these basic commands to be as strict as possible,
 including type-checks. Does that mean having git verify-mergetag which
 verifies that it is being used on a merge commit with embedded mergetag?
 
 (BTW: Is there anything keeping a non-merge commit from having an
 embedded (merge) tag?)
 
 Michael

Another observation:

git merge -S branch
#fix conflict
git commit # Merge --continue

forgets that the merge was supposed to be signed. One needs to commit
-S to sign the merge.

Another one:
The color for merge tags in log --color is terrible (colored
background)...

Michael
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-27 Thread Michael J Gruber
Michael J Gruber venit, vidit, dixit 27.06.2014 14:49:
 Michael J Gruber venit, vidit, dixit 27.06.2014 14:31:
 Jeff King venit, vidit, dixit 16.06.2014 22:39:
 On Mon, Jun 16, 2014 at 01:34:20PM -0700, Junio C Hamano wrote:

 Your middle example above did make me think of one other thing, though.
 As you noted, we actually have _three_ signature types:

   1. signed tags

   2. signed commits

   3. merges with embedded mergetag headers

 We already have a tool for (1). Michael is adding a tool for (2). How
 would one check (3) in a similar way?

 Hmph, somehow I misread the patch that it was for both 2  3 X-.

 I was just assuming it handles only (2) without checking further, so I
 may be wrong. But I do not think it makes sense to conflate (2) and (3).
 A merge commit may have both, and they are separate signatures.

 For that matter, is there a way to expose (3) currently, besides via
 --show-signature? It does not trigger %GG and friends (nor should it).
 It may make sense to add extra format specifiers for mergetag
 signatures. Though I do not use them myself, so I am not clear on what
 the use case is besides a manual, human verification of a particular
 merge.

 I'm afraid I'm on a weekly git schedule at best, sorry. Just trying to
 catch up on this:

 Admittedly, I simply don't know about 3.. I know only 1. and 2. (and
 don't remember why they are implemented differently).

 Are they documented/decribed somewhere?

 Meanwhile, I'm rebasing on top of the %G related patches by Junio and
 Jeff and hope to send out a v4 later today.

 Michael
 
 OK, found the two commits which git log -Smergetag outputs, but no tests.
 
 A merge commit with embedded signed tag it is, then.
 
 The commit could carry it's own commit signature, couldn't it?
 That would suggest that we use git verify-tag to verify the embedded
 signed tag of a merge commit and git verify-commit to verify the
 commit signature.
 
 OTOH I would like these basic commands to be as strict as possible,
 including type-checks. Does that mean having git verify-mergetag which
 verifies that it is being used on a merge commit with embedded mergetag?

... or an extension ref^{mergetag} to our machinery, defaulting to the
tag object containing the mergetag for the 2nd parent, with an optional
version ref^{mergetag}n?

OTOH, verifying a mergetag involves both looking at the signed tag and
the parent list of the commit. We probably should require signed (merge)
tags on all but the first parent. Oh Can of Worms, oh Can of Worms (Oh
Can'o'Worms to the tune of Oh Canada).

Michael
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-27 Thread Junio C Hamano
Michael J Gruber g...@drmicha.warpmail.net writes:

 A merge commit with embedded signed tag it is, then.

 The commit could carry it's own commit signature, couldn't it?

Yes, an integrator can choose to sign a merge he creates, merging
the work by a contributor who gave him a pull-request for a tag
signed by the contributor.  The resulting commit will embed the
contributor's signature to let historians verify the second parent,
as well as the integrator's signature to allow verification of the
merge result.  The integrator does not need to keep the signed tag
used as an implementation detail of transferring the signature of
the contributor, and in general such a signed tag used only to
request pulls is not available to the general public and historians
after such a merge is created.

As these signatures are part of a commit object, git verify-commit
would be the logical place to validate them, if we were to do so.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-27 Thread Junio C Hamano
Michael J Gruber g...@drmicha.warpmail.net writes:

 ... or an extension ref^{mergetag} to our machinery, defaulting to the
 tag object containing the mergetag for the 2nd parent, with an optional
 version ref^{mergetag}n?

One thing you should not forget is that with mergetag, the original
tag object is not even necessary to exist in the repository, and
often the original tag will not be propagated to the general public.

You _could_ extract the necessary information from the commit that
merges a signed tag to recreate the tag, but for what purpose?  Your
$commit^{mergetag}n needs to recreate the named tag object but
it is unclear to me how you envision it to be used.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-27 Thread Jeff King
On Fri, Jun 27, 2014 at 11:36:47AM -0700, Junio C Hamano wrote:

 Michael J Gruber g...@drmicha.warpmail.net writes:
 
  A merge commit with embedded signed tag it is, then.
 
  The commit could carry it's own commit signature, couldn't it?
 
 Yes, an integrator can choose to sign a merge he creates, merging
 the work by a contributor who gave him a pull-request for a tag
 signed by the contributor.  The resulting commit will embed the
 contributor's signature to let historians verify the second parent,
 as well as the integrator's signature to allow verification of the
 merge result.  The integrator does not need to keep the signed tag
 used as an implementation detail of transferring the signature of
 the contributor, and in general such a signed tag used only to
 request pulls is not available to the general public and historians
 after such a merge is created.
 
 As these signatures are part of a commit object, git verify-commit
 would be the logical place to validate them, if we were to do so.

We already disagreed on this earlier in the discussion, but I have given
it some more thought, and somehow using verify-commit for mergetags
still feels wrong to me. Let me see if I can put it into words.

First off, I agree that verify-tag is probably not the right place.
There _is_ no tag object to verify anymore (the only reason it is a tag
at all is that the signature came out of what once was a tag).

Let us imagine that we have a verify-commit that verifies commit
signatures made by commit -S. If I run verify-commit foo, that
implies to me two things:

  1. I am verifying the signature over the contents of foo.

 But the mergetag is _not_ a statement about foo; the person who
 signed it never saw foo. It is a statement about foo^2 at best,
 or possibly about the whole history of foo^1..foo^2.

  2. I am verifying _only_ the contents of foo. That is, I expect people
 to use commit -S to cryptographically claim authorship of a
 commit. Whereas with tags, I think we have typically taken them to
 mean I have signed the tip of a segment of history, and I am
 taking responsibility for the final state (e.g., signing release
 tags).

 I realize that this claim is somewhat tenuous. It's not something
 inherent in the crypto, but rather in the social convention of what
 it means to sign a commit. One could easily say signing a commit
 is about signing the whole tree state. But I would ask, then: what
 is the point of signing a commit versus signing a tag?  I think
 that people who wanted commit signatures wanted them to give a
 stronger guarantee of authorship of individual commits.

 Git has largely stayed agnostic about what such signatures mean.
 But if we accept that some projects _are_ going to make that
 distinction, I think conflating verification of the two within the
 same command leads to a potential for confusion.

So for that reason, I think I'd be in favor of simply treating mergetag
signatures as a separate, third entity. Give them their own
%G-specifiers, and give them a separate plumbing command. Let projects
work out how they want to use them, but do not create any particular
affiliation between mergetags and commit signatures (nor between tag
signatures and mergetag signatures).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-16 Thread Michael J Gruber
Junio C Hamano venit, vidit, dixit 13.06.2014 19:06:
 Jeff King p...@peff.net writes:
 
 I realize this isn't really your itch to scratch. It's just that when I
 see a description like verify a commit, I wonder what exactly verify
 means.
 
 I think that is an important point.  If a tool only verifies the
 signature of the commit when conceivably other aspect of it could
 also be verified but we cannot decide how or we decide we should not
 dictate one-way-fits-all, using a generic name verify-commit or
 verify without marking that it is currently only on the signature
 clearly somewhere might close the door to the future.
 
 git verify object::
 Verify whatever we currently deem is appropriate for the
 given type of object.
 
 git verify --gpg-signature::
   Verify the GPG signature for a signed tag, a signed commit,
 or a merge with signed tags.
 
 git verify --commit-author committish::
   Verify the GPG signer matches the author  header of the
   commit.
 
 and more, perhaps?
 

So what does that mean? And what does it mean for verify-tag, which does
nothing but checking the return code from gpg, just like the proposed
verify-commit?

As pointed out, strict verification is a matter of policy, very much
like accepting certain ref updates etc. is. Do we want a signature
verification hook?

We currently don't have a scriptable commit signature verification in
the same way we have one for tag signatures. That's the gap that I
wanted to fill in in response to a blog post about commit signatures in
git. But it's not my itch, I don't use signatures.

Michael
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-16 Thread Jeff King
On Fri, Jun 13, 2014 at 10:06:10AM -0700, Junio C Hamano wrote:

 Jeff King p...@peff.net writes:
 
  I realize this isn't really your itch to scratch. It's just that when I
  see a description like verify a commit, I wonder what exactly verify
  means.
 
 I think that is an important point.  If a tool only verifies the
 signature of the commit when conceivably other aspect of it could
 also be verified but we cannot decide how or we decide we should not
 dictate one-way-fits-all, using a generic name verify-commit or
 verify without marking that it is currently only on the signature
 clearly somewhere might close the door to the future.
 
 git verify object::
 Verify whatever we currently deem is appropriate for the
 given type of object.
 
 git verify --gpg-signature::
   Verify the GPG signature for a signed tag, a signed commit,
 or a merge with signed tags.
 
 git verify --commit-author committish::
   Verify the GPG signer matches the author  header of the
   commit.
 
 and more, perhaps?

That is certainly the direction I was thinking of when I suggested git
verify.

However, I do not think it is too bad a thing to add a verify-commit
that matches verify-tag, as long as they do the exact same thing
(namely, check the gpg signature). We may find it is later obsoleted by
git verify --gpg-signature, but given that verify-tag is already there
and will remain for compatibility, I don't think we are increasing the
cognitive load too much.

Your middle example above did make me think of one other thing, though.
As you noted, we actually have _three_ signature types:

  1. signed tags

  2. signed commits

  3. merges with embedded mergetag headers

We already have a tool for (1). Michael is adding a tool for (2). How
would one check (3) in a similar way?

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-16 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 On Fri, Jun 13, 2014 at 10:06:10AM -0700, Junio C Hamano wrote:
 ...
 and more, perhaps?

 That is certainly the direction I was thinking of when I suggested git
 verify.

 However, I do not think it is too bad a thing to add a verify-commit
 that matches verify-tag, as long as they do the exact same thing
 (namely, check the gpg signature). We may find it is later obsoleted by
 git verify --gpg-signature, but given that verify-tag is already there
 and will remain for compatibility, I don't think we are increasing the
 cognitive load too much.

Yup, I think we are exactly on the same page.

Thanks for sanity-checking.

 Your middle example above did make me think of one other thing, though.
 As you noted, we actually have _three_ signature types:

   1. signed tags

   2. signed commits

   3. merges with embedded mergetag headers

 We already have a tool for (1). Michael is adding a tool for (2). How
 would one check (3) in a similar way?

Hmph, somehow I misread the patch that it was for both 2  3 X-.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-16 Thread Jeff King
On Mon, Jun 16, 2014 at 01:34:20PM -0700, Junio C Hamano wrote:

  Your middle example above did make me think of one other thing, though.
  As you noted, we actually have _three_ signature types:
 
1. signed tags
 
2. signed commits
 
3. merges with embedded mergetag headers
 
  We already have a tool for (1). Michael is adding a tool for (2). How
  would one check (3) in a similar way?
 
 Hmph, somehow I misread the patch that it was for both 2  3 X-.

I was just assuming it handles only (2) without checking further, so I
may be wrong. But I do not think it makes sense to conflate (2) and (3).
A merge commit may have both, and they are separate signatures.

For that matter, is there a way to expose (3) currently, besides via
--show-signature? It does not trigger %GG and friends (nor should it).
It may make sense to add extra format specifiers for mergetag
signatures. Though I do not use them myself, so I am not clear on what
the use case is besides a manual, human verification of a particular
merge.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-13 Thread Jeff King
On Fri, Jun 06, 2014 at 04:15:28PM +0200, Michael J Gruber wrote:

 Commit signatures can be verified using git show -s --show-signature
 or the %G? pretty format and parsing the output, which is well suited
 for user inspection, but not for scripting.
 
 Provide a command verify-commit which is analogous to verify-tag: It
 returns 0 for good signatures and non-zero otherwise, has the gpg output
 on stderr and (optionally) the commit object on stdout, sans the
 signature, just like verify-tag does.
 
 Signed-off-by: Michael J Gruber g...@drmicha.warpmail.net

I think the general direction of this series is reasonable.

Did you give any thought to just having a git verify command, instead
of separate tag/verify commands?

Another thought, that may be orthogonal to your series: what does it
mean to verify a commit? We check for _some_ signature from a key that
is in your keyring. But we do not check whether the signature matches
the committer field (or for tags, the tagger field). You have to parse
the gpg output, run git cat-file, and then correlate the two. Should
there be an option to have git check that one of the signed uids from
gpg matches the commit's committer?

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-13 Thread Michael J Gruber
Jeff King venit, vidit, dixit 13.06.2014 10:02:
 On Fri, Jun 06, 2014 at 04:15:28PM +0200, Michael J Gruber wrote:
 
 Commit signatures can be verified using git show -s --show-signature
 or the %G? pretty format and parsing the output, which is well suited
 for user inspection, but not for scripting.

 Provide a command verify-commit which is analogous to verify-tag: It
 returns 0 for good signatures and non-zero otherwise, has the gpg output
 on stderr and (optionally) the commit object on stdout, sans the
 signature, just like verify-tag does.

 Signed-off-by: Michael J Gruber g...@drmicha.warpmail.net
 
 I think the general direction of this series is reasonable.
 
 Did you give any thought to just having a git verify command, instead
 of separate tag/verify commands?

Yes. (mathematician's answer)

You know not only the outcome but also why I refrained from doing so:
compatibility. We would need to deprecate verify-tag.

But there is also a more subtle reason: If you want to verify a signed
commit, you want to be sure that it actually is a commit. verify could
easily branch code paths based on the object type, but I'm not sure that
is desirable, at least not by default.

 Another thought, that may be orthogonal to your series: what does it
 mean to verify a commit? We check for _some_ signature from a key that
 is in your keyring. But we do not check whether the signature matches
 the committer field (or for tags, the tagger field). You have to parse
 the gpg output, run git cat-file, and then correlate the two. Should
 there be an option to have git check that one of the signed uids from
 gpg matches the commit's committer?
 
 -Peff
 

That is a general issue with verifying signatures: it can be automated
only if you employ a strict trust model and a very limited keyring.
valid signature means only as much as the signatures that your gpg
accepts can be really trusted.

Comparing uid's really buys you nothing in the sense that everyone can
have a key with uid Jeff King p...@peff.net signed by some other
keys. On the other hand, it's perfectly OK to use different uids for git
commits and signatures. The e-mail address I use for the git list and
commits, for example, is clearly a plus address, which helps me
organize things; my personal key has the primary address as uid.

I really think all this is up to local policies for individual use cases.

Michael
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-13 Thread Jeff King
On Fri, Jun 13, 2014 at 11:55:22AM +0200, Michael J Gruber wrote:

  Did you give any thought to just having a git verify command, instead
  of separate tag/verify commands?
 
 Yes. (mathematician's answer)

Cute.

 You know not only the outcome but also why I refrained from doing so:
 compatibility. We would need to deprecate verify-tag.

Yes, we'd certainly leave verify-tag in place for compatibility. I don't
think that makes git verify a bad idea necessarily, if it is a better
interface. But...

 But there is also a more subtle reason: If you want to verify a signed
 commit, you want to be sure that it actually is a commit. verify could
 easily branch code paths based on the object type, but I'm not sure that
 is desirable, at least not by default.

Yes, I wasn't sure about that part. I think it really depends on what
people want to use it for. I was thinking more of a porcelain, anyway,
to just check whatever signatures are available. But I don't really sign
my commits right now anyway, so I'm somewhat guessing.

Even if we decide to do something like that, I suppose having
verify-commit isn't the end of the world. It could just remain the
plumbing interface, as verify-tag would. So I don't think my half-formed
thoughts are any reason to block your series.

 That is a general issue with verifying signatures: it can be automated
 only if you employ a strict trust model and a very limited keyring.
 valid signature means only as much as the signatures that your gpg
 accepts can be really trusted.
 
 Comparing uid's really buys you nothing in the sense that everyone can
 have a key with uid Jeff King p...@peff.net signed by some other
 keys.

Sort of. The crypto proves that the commit was signed by a particular
key, and then there are two mappings:

  1. What is the identity associated with that key?

  2. Is that identity somebody who should have signed the commit?

We assume that GPG takes care of the first one with the web of trust.
Even if you have the key and can check the signature, it will still
complain about an untrusted uid (and we reflect that with 'U' in the gpg
status). There is no point in looking at step 2 if step 1 did not check
out.

For the second one, I think it really depends on the project workflow,
and you may even want multiple policies within a project (e.g., perhaps
only some uids can merge to master). But one obvious check we can make
is does the identity in the commit data match one of the uids?. True,
you don't _need_ that; you can always just use %GS, and throw away the
committer and author headers. But we show those names in lots of output.
You could, for example, verify that each commit's author id matches
its gpg signature, and then use the regular tools to do further work
(e.g., running git blame), and be confident that the author you see
matches the signature.

This should definitely be optional. Even something as simple as author
id matches the gpg key would not always work (for example, in git.git
we pick patches from the list, which means only Junio can sign the
objects, but he is not the author). But just because it is optional does
not mean it would not be a useful tool for some workflows.

 On the other hand, it's perfectly OK to use different uids for git
 commits and signatures. The e-mail address I use for the git list and
 commits, for example, is clearly a plus address, which helps me
 organize things; my personal key has the primary address as uid.
 
 I really think all this is up to local policies for individual use cases.

Very much agreed. My suggestion was more about providing tools for
people to build those policies.

I realize this isn't really your itch to scratch. It's just that when I
see a description like verify a commit, I wonder what exactly verify
means.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-13 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 I realize this isn't really your itch to scratch. It's just that when I
 see a description like verify a commit, I wonder what exactly verify
 means.

I think that is an important point.  If a tool only verifies the
signature of the commit when conceivably other aspect of it could
also be verified but we cannot decide how or we decide we should not
dictate one-way-fits-all, using a generic name verify-commit or
verify without marking that it is currently only on the signature
clearly somewhere might close the door to the future.

git verify object::
Verify whatever we currently deem is appropriate for the
given type of object.

git verify --gpg-signature::
Verify the GPG signature for a signed tag, a signed commit,
or a merge with signed tags.

git verify --commit-author committish::
Verify the GPG signer matches the author  header of the
commit.

and more, perhaps?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-11 Thread Michael J Gruber


On 6. Juni 2014 16:15:28 MESZ, Michael J Gruber g...@drmicha.warpmail.net 
wrote:
Commit signatures can be verified using git show -s --show-signature
or the %G? pretty format and parsing the output, which is well suited
for user inspection, but not for scripting.

Provide a command verify-commit which is analogous to verify-tag:
It
returns 0 for good signatures and non-zero otherwise, has the gpg
output
on stderr and (optionally) the commit object on stdout, sans the
signature, just like verify-tag does.

Signed-off-by: Michael J Gruber g...@drmicha.warpmail.net
---
 Documentation/git-verify-commit.txt | 28 +++
 Makefile|  1 +
 builtin.h   |  1 +
builtin/verify-commit.c | 98
+
 command-list.txt|  1 +
 git.c   |  1 +
 6 files changed, 130 insertions(+)
 create mode 100644 Documentation/git-verify-commit.txt
 create mode 100644 builtin/verify-commit.c

diff --git a/Documentation/git-verify-commit.txt
b/Documentation/git-verify-commit.txt
new file mode 100644
index 000..dcd7803
--- /dev/null
+++ b/Documentation/git-verify-commit.txt
@@ -0,0 +1,28 @@
+git-verify-commit(1)
+=

That line will need 3 more = thanks to asciidoc stubbornness.

v2 plus the tests coming tomorrow when my dev box is online again.

+
+NAME
+
+git-verify-commit - Check the GPG signature of commits
+
+SYNOPSIS
+
+[verse]
+'git verify-commit' commit...
+
+DESCRIPTION
+---
+Validates the gpg signature created by 'git commit -S'.
+
+OPTIONS
+---
+-v::
+--verbose::
+  Print the contents of the commit object before validating it.
+
+commit...::
+  SHA-1 identifiers of Git commit objects.
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Makefile b/Makefile
index 07ea105..b92418d 100644
--- a/Makefile
+++ b/Makefile
@@ -999,6 +999,7 @@ BUILTIN_OBJS += builtin/update-ref.o
 BUILTIN_OBJS += builtin/update-server-info.o
 BUILTIN_OBJS += builtin/upload-archive.o
 BUILTIN_OBJS += builtin/var.o
+BUILTIN_OBJS += builtin/verify-commit.o
 BUILTIN_OBJS += builtin/verify-pack.o
 BUILTIN_OBJS += builtin/verify-tag.o
 BUILTIN_OBJS += builtin/write-tree.o
diff --git a/builtin.h b/builtin.h
index c47c110..5d91f31 100644
--- a/builtin.h
+++ b/builtin.h
@@ -128,6 +128,7 @@ extern int cmd_update_server_info(int argc, const
char **argv, const char *prefi
extern int cmd_upload_archive(int argc, const char **argv, const char
*prefix);
extern int cmd_upload_archive_writer(int argc, const char **argv, const
char *prefix);
 extern int cmd_var(int argc, const char **argv, const char *prefix);
+extern int cmd_verify_commit(int argc, const char **argv, const char
*prefix);
extern int cmd_verify_tag(int argc, const char **argv, const char
*prefix);
extern int cmd_version(int argc, const char **argv, const char
*prefix);
extern int cmd_whatchanged(int argc, const char **argv, const char
*prefix);
diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c
new file mode 100644
index 000..69b7c6d
--- /dev/null
+++ b/builtin/verify-commit.c
@@ -0,0 +1,98 @@
+/*
+ * Builtin git commit-commit
+ *
+ * Copyright (c) 2014 Michael J Gruber g...@drmicha.warpmail.net
+ *
+ * Based on git-verify-tag
+ */
+#include cache.h
+#include builtin.h
+#include commit.h
+#include run-command.h
+#include signal.h
+#include parse-options.h
+#include gpg-interface.h
+
+static const char * const verify_commit_usage[] = {
+  N_(git verify-commit [-v|--verbose] commit...),
+  NULL
+};
+
+static int run_gpg_verify(const unsigned char *sha1, const char *buf,
unsigned long size, int verbose)
+{
+  struct signature_check signature_check;
+
+  memset(signature_check, 0, sizeof(signature_check));
+
+  check_commit_signature(lookup_commit(sha1), signature_check);
+
+  if (verbose  signature_check.payload)
+  fputs(signature_check.payload, stdout);
+
+  if (signature_check.gpg_output)
+  fputs(signature_check.gpg_output, stderr);
+
+  free(signature_check.gpg_output);
+  free(signature_check.gpg_status);
+  free(signature_check.signer);
+  free(signature_check.key);
+  return signature_check.result != 'G';
+}
+
+static int verify_commit(const char *name, int verbose)
+{
+  enum object_type type;
+  unsigned char sha1[20];
+  char *buf;
+  unsigned long size;
+  int ret;
+
+  if (get_sha1(name, sha1))
+  return error(commit '%s' not found., name);
+
+  type = sha1_object_info(sha1, NULL);
+  if (type != OBJ_COMMIT)
+  return error(%s: cannot verify a non-commit object of type 
%s.,
+  name, typename(type));
+
+  buf = read_sha1_file(sha1, type, size);
+  if (!buf)
+  return error(%s: unable to read file., name);
+
+  ret = run_gpg_verify(sha1, buf, size, verbose);
+
+  free(buf);
+  

[PATCH 3/3] verify-commit: scriptable commit signature verification

2014-06-06 Thread Michael J Gruber
Commit signatures can be verified using git show -s --show-signature
or the %G? pretty format and parsing the output, which is well suited
for user inspection, but not for scripting.

Provide a command verify-commit which is analogous to verify-tag: It
returns 0 for good signatures and non-zero otherwise, has the gpg output
on stderr and (optionally) the commit object on stdout, sans the
signature, just like verify-tag does.

Signed-off-by: Michael J Gruber g...@drmicha.warpmail.net
---
 Documentation/git-verify-commit.txt | 28 +++
 Makefile|  1 +
 builtin.h   |  1 +
 builtin/verify-commit.c | 98 +
 command-list.txt|  1 +
 git.c   |  1 +
 6 files changed, 130 insertions(+)
 create mode 100644 Documentation/git-verify-commit.txt
 create mode 100644 builtin/verify-commit.c

diff --git a/Documentation/git-verify-commit.txt 
b/Documentation/git-verify-commit.txt
new file mode 100644
index 000..dcd7803
--- /dev/null
+++ b/Documentation/git-verify-commit.txt
@@ -0,0 +1,28 @@
+git-verify-commit(1)
+=
+
+NAME
+
+git-verify-commit - Check the GPG signature of commits
+
+SYNOPSIS
+
+[verse]
+'git verify-commit' commit...
+
+DESCRIPTION
+---
+Validates the gpg signature created by 'git commit -S'.
+
+OPTIONS
+---
+-v::
+--verbose::
+   Print the contents of the commit object before validating it.
+
+commit...::
+   SHA-1 identifiers of Git commit objects.
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Makefile b/Makefile
index 07ea105..b92418d 100644
--- a/Makefile
+++ b/Makefile
@@ -999,6 +999,7 @@ BUILTIN_OBJS += builtin/update-ref.o
 BUILTIN_OBJS += builtin/update-server-info.o
 BUILTIN_OBJS += builtin/upload-archive.o
 BUILTIN_OBJS += builtin/var.o
+BUILTIN_OBJS += builtin/verify-commit.o
 BUILTIN_OBJS += builtin/verify-pack.o
 BUILTIN_OBJS += builtin/verify-tag.o
 BUILTIN_OBJS += builtin/write-tree.o
diff --git a/builtin.h b/builtin.h
index c47c110..5d91f31 100644
--- a/builtin.h
+++ b/builtin.h
@@ -128,6 +128,7 @@ extern int cmd_update_server_info(int argc, const char 
**argv, const char *prefi
 extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
 extern int cmd_upload_archive_writer(int argc, const char **argv, const char 
*prefix);
 extern int cmd_var(int argc, const char **argv, const char *prefix);
+extern int cmd_verify_commit(int argc, const char **argv, const char *prefix);
 extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);
 extern int cmd_version(int argc, const char **argv, const char *prefix);
 extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c
new file mode 100644
index 000..69b7c6d
--- /dev/null
+++ b/builtin/verify-commit.c
@@ -0,0 +1,98 @@
+/*
+ * Builtin git commit-commit
+ *
+ * Copyright (c) 2014 Michael J Gruber g...@drmicha.warpmail.net
+ *
+ * Based on git-verify-tag
+ */
+#include cache.h
+#include builtin.h
+#include commit.h
+#include run-command.h
+#include signal.h
+#include parse-options.h
+#include gpg-interface.h
+
+static const char * const verify_commit_usage[] = {
+   N_(git verify-commit [-v|--verbose] commit...),
+   NULL
+};
+
+static int run_gpg_verify(const unsigned char *sha1, const char *buf, unsigned 
long size, int verbose)
+{
+   struct signature_check signature_check;
+
+   memset(signature_check, 0, sizeof(signature_check));
+
+   check_commit_signature(lookup_commit(sha1), signature_check);
+
+   if (verbose  signature_check.payload)
+   fputs(signature_check.payload, stdout);
+
+   if (signature_check.gpg_output)
+   fputs(signature_check.gpg_output, stderr);
+
+   free(signature_check.gpg_output);
+   free(signature_check.gpg_status);
+   free(signature_check.signer);
+   free(signature_check.key);
+   return signature_check.result != 'G';
+}
+
+static int verify_commit(const char *name, int verbose)
+{
+   enum object_type type;
+   unsigned char sha1[20];
+   char *buf;
+   unsigned long size;
+   int ret;
+
+   if (get_sha1(name, sha1))
+   return error(commit '%s' not found., name);
+
+   type = sha1_object_info(sha1, NULL);
+   if (type != OBJ_COMMIT)
+   return error(%s: cannot verify a non-commit object of type 
%s.,
+   name, typename(type));
+
+   buf = read_sha1_file(sha1, type, size);
+   if (!buf)
+   return error(%s: unable to read file., name);
+
+   ret = run_gpg_verify(sha1, buf, size, verbose);
+
+   free(buf);
+   return ret;
+}
+
+static int git_verify_commit_config(const char *var, const char *value, void 
*cb)
+{
+   int status = git_gpg_config(var, value, cb);
+   if (status)