Subject: Re: [PATCH 16/18] receive-pack: GPG-validate push certificates

From: David Turner <[email-masked]>
Date: Thu, 21 Aug 2014 19:59:01 -0400

On Wed, 2014-08-20 at 12:38 -0700, Junio C Hamano wrote:
> David Turner <[email-masked]> writes:
> 
> > On Wed, 2014-08-20 at 10:29 -0700, Junio C Hamano wrote:
> >> On Wed, Aug 20, 2014 at 9:56 AM, David Turner <[email-masked]> wrote:
> >> > On Tue, 2014-08-19 at 15:06 -0700, Junio C Hamano wrote:
> >> >> Reusing the GPG signature check helpers we already have, verify
> >> >> the signature in receive-pack and give the results to the hooks
> >> >> via GIT_PUSH_CERT_{SIGNER,KEY,STATUS} environment variables.
> >> >>
> >> >> Policy decisions, such as accepting or rejecting a good signature by
> >> >> a key that is not fully trusted, is left to the hook and kept
> >> >> outside of the core.
> >> >
> >> > If I understand correctly, the hook does not have enough information to
> >> > make this decision, because it is missing the date from the signature.
> >> 
> >> The full certificate is available to the hook so anything we can do the hook
> >> has enough information to do ;-)  But of course we should try to make it
> >> easier for the hook to validate the request.
> >
> > Excellent, then motivated hooks can do the right thing.
> >
> >> > This might allow an old signed push to be replayed, moving the head of a
> >> > branch to an older state (say, one lacking the latest security updates).
> >> 
> >> ... with old-sha1 recorded in the certificate?
> >
> > That does prevent most replays, but it does not prevent resurrection of
> > a deleted branch by a replay of its initial creation (nor an undo of a
> > force-push to rollback).  So I think we still need timestamps, but
> > parsing them out of the cert is not terrible.
> 
> As I aleady mentioned elsewhere, a more problematic thing about the
> push certificate as presented in 15/18 is that it does not say
> anything about where the push is going.  If you can capture a trial
> push to some random test repository I do with my signed push
> certificate, you could replay it to my public repository hosted at
> a more official site (say, k.org in the far distant future where it
> does not rely on ssh authentication to protect their services but
> uses the GPG signature on the push certificate to make sure it is I
> who is pushing).
> 
> We can add a new "pushed-to <repository URL>" header line to the
> certificate, next to "pushed-by <ident> <time>", and have the
> receiving end verify that it matches to prevent such a replay.  I
> wonder if we can further extend it to avoid replays to the same
> repository.

I think but am not certain that pushed-to <repository URL>, along with
the pushed-by <ident> <time> means that the nonce is not needed. The
nonce might make replays harder, but pushed-to/pushed-by makes replays
useless since the receiving server can determine that the user intended
to take this action at this time on this server.