Mailing List Archive

Git release tagging best practices
Hi GnuPG folks--

I was just reviewing the cryptographically-signed git tags that
represent releases of GnuPG, thanks to the 2.2.14 release, which i'm
aiming to upload into debian experimental later today. I enjoy the
commentary and media recommendations included in the git tag messages,
but i think they aren't currently very useful for downstream verifiers.

I recommend making a standardized message for each future release tag,
starting with a single line "GnuPG version $version". This allows any
downstream to defend against a possible obscure attack against any other
repositories of software that you might also sign. (and it would defend
GnuPG against impersonation attacks from any other such project as well)

So, rather than doing:

git tag -s -m 'Just another boring release' gnupg-2.2.15

Instead, please do:

git tag -s -m 'GnuPG version 2.2.15' gnupg-2.2.15

The issue is that the thing that is being tagged is not clearly
recognizable as GnuPG -- it's just something signed, by OpenPGP
certificate 0xD8692123C4065DEA5E0F3AB5249B39D24F25E3B6. People might
evaluate it as a a GnuPG release because of where they happen to find
the git repository (e.g. the URL they chose), but the same git
repository can be replicated to some other location, and the signed tag
will show up there as well.

By ensuring that your git tag messages are specific to the project that
you're signing, and that they include the release information that you
are trying to convey, someone verifying your signed tag on *any*
repository can defend against this attack by ensuring not only your
signature, but also that the signing message is related to the project
that they care about.

If you want to include reading recommendations and other interesting
commentary, you can still do that by adding additional -m options (git
will concatenate them with blank lines between). As long as you reserve
the first line as a standardized and unambiguous form, then that gives
automated downstream checks something to concretely verify, rather than
having them guess that this is actually the right new tag, based on
non-verifiable features like tag name, repository location, etc.

I'm recommending these as best practices, while acknowledging that very
few projects follow them yet. I'm hoping that GnuPG can help to lead
the way in establishing this sort of convention, so that i can encourage
downstream tools to verify meaningful signatures, rather than just
"something that Werner or gniibe signed".

All the best,

--dkg

PS Note that the *name* of the tag itself is not covered by the
cryptographic signature (it is possible to rename tags without
modifying their cryptographic validity). This is why I recommend
using the tag message to contain this information rather than the tag
name itself.
Re: Git release tagging best practices [ In reply to ]
On 19/03/2019 17:32, Daniel Kahn Gillmor wrote:
> PS Note that the *name* of the tag itself is not covered by the
> cryptographic signature (it is possible to rename tags without
> modifying their cryptographic validity). This is why I recommend
> using the tag message to contain this information rather than the tag
> name itself.

Are you sure? I looked at what the exact data that is signed is, and it
seems to me it does include the name:

--8<---------------cut here---------------start------------->8---
$ cat .git/refs/tags/gnupg-2.2.13
baae95e8359ab45ff64414a8e8387997bb828a1b
$ git cat-file tag baae95e8359ab45ff64414a8e8387997bb828a1b
object 7922e2dd1c7eee48a8a2cf4799827942489ddd0f
type commit
tag gnupg-2.2.13
tagger Werner Koch <wk@gnupg.org> 1549985965 +0100

You may want to watch the Ellsberg/Chomsky discussion
at <https://riseuptimes.org/2018/04/25/daniel-ellsberg-and-noam-chomsky-discuss-nuclear-war/>
or at <https://theintercept.com/chomsky-ellsberg/>
-----BEGIN PGP SIGNATURE-----

iQEzBAABCAAdFiEE2GkhI8QGXepeDzq1JJs50k8l47YFAlxi6SwACgkQJJs50k8l
47Zczwf/XGMMUCWnWsD+nVzmAYaBPp76/CBkG6qeZkvAVyFbhv9RGs4SRxp4rK1r
NT9tnjHyETIh/Yoc0uDgIdt2neaicc2LKrVgzMpsOKutFyKrH5hNsfCrMAu/NEC8
6AEFcRlS0WWgQTehiwVjCRf/hALYW1KjeL6HR2J1b58VAlABa78H+tY8Z+wFqFcf
XJgQ8gR1QtkMuLnGqlN/6sLjN0BKsBqMZvt/T9aljpH6RJuzTyIUjln1uDl43htj
sDGa7BZtmf7XiEjcX62NS6yDfuOyw0guDFkOvsIt3IBqtDWAxY7qc5do0CQjOU8t
BdrTflO5D1a9ZISgA+6wO/nJAIvFwA==
=F3BP
-----END PGP SIGNATURE-----
--8<---------------cut here---------------end--------------->8---

So let's split that into:

the-tag.txt:
--8<---------------cut here---------------start------------->8---
object 7922e2dd1c7eee48a8a2cf4799827942489ddd0f
type commit
tag gnupg-2.2.13
tagger Werner Koch <wk@gnupg.org> 1549985965 +0100

You may want to watch the Ellsberg/Chomsky discussion
at <https://riseuptimes.org/2018/04/25/daniel-ellsberg-and-noam-chomsky-discuss-nuclear-war/>
or at <https://theintercept.com/chomsky-ellsberg/>
--8<---------------cut here---------------end--------------->8---

the-tag.sig:
--8<---------------cut here---------------start------------->8---
-----BEGIN PGP SIGNATURE-----

iQEzBAABCAAdFiEE2GkhI8QGXepeDzq1JJs50k8l47YFAlxi6SwACgkQJJs50k8l
47Zczwf/XGMMUCWnWsD+nVzmAYaBPp76/CBkG6qeZkvAVyFbhv9RGs4SRxp4rK1r
NT9tnjHyETIh/Yoc0uDgIdt2neaicc2LKrVgzMpsOKutFyKrH5hNsfCrMAu/NEC8
6AEFcRlS0WWgQTehiwVjCRf/hALYW1KjeL6HR2J1b58VAlABa78H+tY8Z+wFqFcf
XJgQ8gR1QtkMuLnGqlN/6sLjN0BKsBqMZvt/T9aljpH6RJuzTyIUjln1uDl43htj
sDGa7BZtmf7XiEjcX62NS6yDfuOyw0guDFkOvsIt3IBqtDWAxY7qc5do0CQjOU8t
BdrTflO5D1a9ZISgA+6wO/nJAIvFwA==
=F3BP
-----END PGP SIGNATURE-----
--8<---------------cut here---------------end--------------->8---

And presto:

--8<---------------cut here---------------start------------->8---
$ gpg --verify the-tag.{sig,txt}
gpg: Signature made Tue 12 Feb 2019 16:41:32 CET
gpg: using RSA key D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
gpg: Good signature from "Werner Koch (dist sig)" [full]
gpg: werner koch (dist sig): Verified [REDACTED]
--8<---------------cut here---------------end--------------->8---

Note that the third line of the signed data reads "tag gnupg-2.2.13". So
is there some loophole that means this is not useful?

I'm not saying that the first line of tag messages shouldn't be
standardized as you propose, I'm just debating the correctness of the
quoted assertion.

Cheers,

Peter.

--
I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.
You can send me encrypted mail if you want some privacy.
My key is available at <http://digitalbrains.com/2012/openpgp-key-peter>
Re: Git release tagging best practices [ In reply to ]
On Tue 2019-03-19 19:09:25 +0100, Peter Lebbing wrote:
> On 19/03/2019 17:32, Daniel Kahn Gillmor wrote:
>> PS Note that the *name* of the tag itself is not covered by the
>> cryptographic signature (it is possible to rename tags without
>> modifying their cryptographic validity). This is why I recommend
>> using the tag message to contain this information rather than the tag
>> name itself.
>
> Are you sure? I looked at what the exact data that is signed is, and it
> seems to me it does include the name:

That's interesting, thanks for pointing it out. There are two places
for the name of the tag, and i think you're right that the signatures
made by modern git tags do seem to include the tag name (gnupg is ahead
of the game here, fwiw: many projects don't include the project name in
their tag name, and just go with tags like v2.2.13, which leave the same
issue open). I didn't think that they used to do that, but maybe they
did and i just never noticed.

> Note that the third line of the signed data reads "tag gnupg-2.2.13". So
> is there some loophole that means this is not useful?

To test that, i've just pushed https://gitlab.com/dkg/renaming-demo.git,
where I've just re-named a different tag issued by Werner.

If you were to clone that repository, you'll note that "git tag -v
gnupg-2.2.13" returns success, even though the contents of the message
don't say "tag gnupg-2.2.13".

So i suppose it depends on how you think people are verifying that tag.
I'd imagine most folks (if they verify the tag at all) just check that
git tag -v $tagname returns 0 (and maybe they check that the tag was
made by a key that they associate with the project).

I wonder whether we "git tag -v" should raise an error if the tag name
within the signature doesn't match the tag name being verified. I've
just sent message-id: <875zsdu41d.fsf@fifthhorseman.net> to
git@vger.kernel.org to ask about improving the situation there (maybe i
need to subscribe to convince them to let my mail through, though, i
don't know).

> I'm not saying that the first line of tag messages shouldn't be
> standardized as you propose, I'm just debating the correctness of the
> quoted assertion.

Thanks for the clarifying question, and for pointing this out!

Regards,

--dkg
Re: Git release tagging best practices [ In reply to ]
Am Mittwoch 20 März 2019 13:28:33 schrieb Daniel Kahn Gillmor:
> I wonder whether we "git tag -v" should raise an error if the tag name
> within the signature doesn't match the tag name being verified.

Here is an interesting writeup, which also compared git and Monotone SCM
signing features:
https://www.mercurial-scm.org/wiki/CommitSigningPlan

As I understand it: hg can sign a specific state of the repository, but
this has other drawbacks. It is good to have some competition on distributed
SCMs. >:)

Regards,
Bernhard

--
www.intevation.de/~bernhard   +49 541 33 508 3-3
Intevation GmbH, Osnabrück, DE; Amtsgericht Osnabrück, HRB 18998
Geschäftsführer Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner
Re: Git release tagging best practices [ In reply to ]
On Tue, 19 Mar 2019 12:32, dkg@fifthhorseman.net said:

> commentary and media recommendations included in the git tag messages,
> but i think they aren't currently very useful for downstream verifiers.

:-)

Frankly, I do not know what to write into the tag message because it
does not make sense to me to repeat what we have in NEWS, which is in
the commit named "Release x.y.z". Maybe I should also change that
commit to read "GnuPG release x.y.z".

> git tag -s -m 'GnuPG version 2.2.15' gnupg-2.2.15

Will do - and maybe add a fortune(1) to the next line.

> I'm recommending these as best practices, while acknowledging that very
> few projects follow them yet. I'm hoping that GnuPG can help to lead

I would also wihs that more commits are signed. With an on-disk key it
does not take any noticeable time, which it does neither when using a
GnuK with an ed25519 key. You just need to have something like

[user]
name = "Alica H. Acker"
email = "ah@example.dev"
signingkey = C1D34B69219E4AEEC0BA1C21E3FDFF218E45B72B

in ~/.gitconfig and when doing tag signing with a different key you can
resort to

git tag -u OTHERKEYID -m 'FOO version 1.2.3' foo-1.2.3


Shalom-Salam,

Werner

--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Re: Git release tagging best practices [ In reply to ]
On Thu, 21 Mar 2019 10:07, bernhard@intevation.de said:

> As I understand it: hg can sign a specific state of the repository, but

git can sign all commits (see signingkey keyword for .gitconfig) which
is a signature of the current state.


Salam-Shalom,

Werner

--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Re: Git release tagging best practices [ In reply to ]
On Wed, 2019-03-20 at 08:28 -0400, Daniel Kahn Gillmor wrote:
> On Tue 2019-03-19 19:09:25 +0100, Peter Lebbing wrote:
> > On 19/03/2019 17:32, Daniel Kahn Gillmor wrote:
> > > PS Note that the *name* of the tag itself is not covered by the
> > > cryptographic signature (it is possible to rename tags without
> > > modifying their cryptographic validity). This is why I
> > > recommend
> > > using the tag message to contain this information rather than
> > > the tag
> > > name itself.
> >
> > Are you sure? I looked at what the exact data that is signed is,
> > and it seems to me it does include the name:

It can't. Remember the name of the tag is metadata which is held in
the git refs file not in the tag itself. The signature of the tag is
over the contents (including header contents like date and parent)
which doesn't include the name.

This means the name of the tag can be changed by changing the refs file
and actually you can erase the tag with no adverse consequences to the
tree. What you can't do is move it to a different parent because that
will cause a verification failure.

> That's interesting, thanks for pointing it out. There are two places
> for the name of the tag, and i think you're right that the signatures
> made by modern git tags do seem to include the tag name (gnupg is
> ahead of the game here, fwiw: many projects don't include the project
> name in their tag name, and just go with tags like v2.2.13, which
> leave the same issue open). I didn't think that they used to do
> that, but maybe they did and i just never noticed.
>
> > Note that the third line of the signed data reads "tag gnupg-
> > 2.2.13". So is there some loophole that means this is not useful?
>
> To test that, i've just pushed https://gitlab.com/dkg/renaming-
> demo.git, where I've just re-named a different tag issued by Werner.
>
> If you were to clone that repository, you'll note that "git tag -v
> gnupg-2.2.13" returns success, even though the contents of the
> message don't say "tag gnupg-2.2.13".
>
> So i suppose it depends on how you think people are verifying that
> tag. I'd imagine most folks (if they verify the tag at all) just
> check that git tag -v $tagname returns 0 (and maybe they check that
> the tag was made by a key that they associate with the project).
>
> I wonder whether we "git tag -v" should raise an error if the tag
> name within the signature doesn't match the tag name being verified.

Absolutely not, at least not globally. Remember the design use case
for signed tags is cryptographically verified pull requests, in which
case there is no name and the tag is discarded after the pull.

> I've just sent message-id: <875zsdu41d.fsf@fifthhorseman.net> to gi
> t@vger.kernel.org to ask about improving the situation there (maybe i
> need to subscribe to convince them to let my mail through, though, i
> don't know).

What you might ask for, if the project locally wanted to add the tag to
the commit and verify it was present, is the same pre- post- -msg hooks
we have for a commit which would allow you to customize on a per-
project basis.

James


> > I'm not saying that the first line of tag messages shouldn't be
> > standardized as you propose, I'm just debating the correctness of
> > the
> > quoted assertion.
>
> Thanks for the clarifying question, and for pointing this out!
>
> Regards,
>
> --dkg
> _______________________________________________
> Gnupg-devel mailing list
> Gnupg-devel@gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gnupg-devel
Re: Git release tagging best practices [ In reply to ]
On Thu 2019-03-21 14:50:56 -0700, James Bottomley wrote:
> It can't. Remember the name of the tag is metadata which is held in
> the git refs file not in the tag itself. The signature of the tag is
> over the contents (including header contents like date and parent)
> which doesn't include the name.

Did you look at Peter's message? Werner's signature over git tag
gnupg-2.2.15 does indeed include "tag gnupg-2.2.15".

> Absolutely not, at least not globally. Remember the design use case
> for signed tags is cryptographically verified pull requests, in which
> case there is no name and the tag is discarded after the pull.

That sounds more like "push certificates" than signed tags to me, but
i'm not up on the details of push certificates, so i might be wrong
about that.

--dkg
Re: Git release tagging best practices [ In reply to ]
On 21/03/2019 22:50, James Bottomley wrote:
> It can't. Remember the name of the tag is metadata which is held in
> the git refs file not in the tag itself. The signature of the tag is
> over the contents (including header contents like date and parent)
> which doesn't include the name.

The third line of the signed data in the real-life example I
demonstrated reads "tag gnupg-2.2.13". That very much looks like the
name of the tag to me! Did you overlook it or do you think it's
something else?

> This means the name of the tag can be changed by changing the refs file
> and actually you can erase the tag with no adverse consequences to the
> tree. What you can't do is move it to a different parent because that
> will cause a verification failure.

But Git could check that the name of the file in .git/refs/tags matches
the name in the signed data.

> Absolutely not, at least not globally. Remember the design use case
> for signed tags is cryptographically verified pull requests, in which
> case there is no name and the tag is discarded after the pull.

I'd rather say "a use case" than "the use case", but okay.

It could easily support both. I don't recognise the use case you
describe, but I presume when you say "there is no name", that the tag is
used through its object hash. Git could skip verifying the name when the
tag is specified through its object hash rather than its name. And if
this is not what you meant, Git could gain a command line option to have
it enforce the name is original, or an option to indicate the name
should not be verified.

Discarding is not a problem.

Cheers,

Peter.

--
I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.
You can send me encrypted mail if you want some privacy.
My key is available at <http://digitalbrains.com/2012/openpgp-key-peter>
Re: Git release tagging best practices [ In reply to ]
I just found the thread on git@vger.kernel.org, I couldn't before (that
user interface at marc.info is not one I like, I just tried
spinics.net).

It seems to cover the subject quite well, I propose we don't do a weak
substitute here.

I should have done this the other way round: decide that is the better
place, and then not answer as I did just now.

Cheers,

Peter.

--
I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.
You can send me encrypted mail if you want some privacy.
My key is available at <http://digitalbrains.com/2012/openpgp-key-peter>
Re: Git release tagging best practices [ In reply to ]
Hi,

Peter Lebbing wrote:
> I just found the thread on git@vger.kernel.org, I couldn't before (that
> user interface at marc.info is not one I like, I just tried
> spinics.net).

Another alternative is https://public-inbox.org/git/ which
is recommended in the git README.md.

The public-inbox.org git list archives there are clonable
via git too (not that you'd want or need to do that for a
simpler search, but it's a nice feature).

--
Todd

_______________________________________________
Gnupg-devel mailing list
Gnupg-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-devel
Re: Git release tagging best practices [ In reply to ]
On Fri, 2019-03-22 at 11:37 +0100, Peter Lebbing wrote:
> On 21/03/2019 22:50, James Bottomley wrote:
> > It can't. Remember the name of the tag is metadata which is held
> > in the git refs file not in the tag itself. The signature of the
> > tag is over the contents (including header contents like date and
> > parent) which doesn't include the name.
>
> The third line of the signed data in the real-life example I
> demonstrated reads "tag gnupg-2.2.13". That very much looks like the
> name of the tag to me! Did you overlook it or do you think it's
> something else?

Ah, actually, I hadn't noticed that was in there.

> > This means the name of the tag can be changed by changing the refs
> > file and actually you can erase the tag with no adverse
> > consequences to the tree. What you can't do is move it to a
> > different parent because that will cause a verification failure.
>
> But Git could check that the name of the file in .git/refs/tags
> matches the name in the signed data.

So that's related to use case, see below.

> > Absolutely not, at least not globally. Remember the design use
> > case for signed tags is cryptographically verified pull requests,
> > in which case there is no name and the tag is discarded after the
> > pull.
>
> I'd rather say "a use case" than "the use case", but okay.

The point is it's the use case signed tags were designed for. It's
what all the cryptographic validation thought around signed tags went
into.

> It could easily support both. I don't recognise the use case you
> describe, but I presume when you say "there is no name", that the tag
> is used through its object hash. Git could skip verifying the name
> when the tag is specified through its object hash rather than its
> name.

When you do git pull remote-tree remote-tag

Git will validate the remote-tag cryptographically and its attachment
point but, because the tag will be discarded after the merge, it
doesn't validate the remote-tag matches the tag name. It's how Linus
ensures cryptographically that what he pulls is what I pushed.

in this workflow the references file is on the remote tree, and the tag
won't become part of the local tree. You could validate that remote-
tag, which will be taken from the remote tree references, matches the
tag name in the signed object but it has no value because the signed
part of the tag is merged into the commit object wholesale, so the
signature can still be verified, but the actual tag itself doesn't
become part of the local tree and is effectively discarded.

You can see this if you do a git log <sha> on a merge pull in the
kernel vs a git cat-file commit <sha>.

> And if this is not what you meant, Git could gain a command line
> option to have it enforce the name is original, or an option to
> indicate the name should not be verified.

OK, but verify for what? git-log <tag> probably. git-archive <tag>
definitely but you need to identify the other commands and use cases.
Cryptographic verification of every tag on all operations would be way
too expensive.

James


> Discarding is not a problem.
>
> Cheers,
>
> Peter.
>
Re: Git release tagging best practices [ In reply to ]
Hello James,

I really think that the git@vger.kernel.org list is the better place to
provide useful input, given that this discussion is also running there
currently. Holding a parallel discussion here is highly inefficient.

Personally, I don't have anything worthwhile to add to that discussion
over there. I see multiple viewpoints expressed, but all of them are
pretty well informed, nothing I can currently think of would enlighten
the minds there.

Peter.

--
I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.
You can send me encrypted mail if you want some privacy.
My key is available at <http://digitalbrains.com/2012/openpgp-key-peter>
Re: Git release tagging best practices [ In reply to ]
On Thu, 21 Mar 2019 23:12, dkg@fifthhorseman.net said:

> Did you look at Peter's message? Werner's signature over git tag
> gnupg-2.2.15 does indeed include "tag gnupg-2.2.15".

Being curious, I also checked this:

--8<---------------cut here---------------start------------->8---
$ git tag -v gnupg-2.2.14
object 813de13e73b01409fabff9859f24c4f23b808796
type commit
tag gnupg-2.2.14
tagger Werner Koch <wk@gnupg.org> 1552991853 +0100

Just another boring release
[...]
gpg: enabled debug flags: hashing
gpg: Signature made Tue Mar 19 11:37:33 2019 CET
gpg: using RSA key D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
gpg: Good signature from "Werner Koch (dist sig)" [ultimate]
--8<---------------cut here---------------end--------------->8---

And here is the actual hashed data:

--8<---------------cut here---------------start------------->8---
00000000 6f 62 6a 65 63 74 20 38 31 33 64 65 31 33 65 37 |object 813de13e7|
00000010 33 62 30 31 34 30 39 66 61 62 66 66 39 38 35 39 |3b01409fabff9859|
00000020 66 32 34 63 34 66 32 33 62 38 30 38 37 39 36 0a |f24c4f23b808796.|
00000030 74 79 70 65 20 63 6f 6d 6d 69 74 0a 74 61 67 20 |type commit.tag |
00000040 67 6e 75 70 67 2d 32 2e 32 2e 31 34 0a 74 61 67 |gnupg-2.2.14.tag|
00000050 67 65 72 20 57 65 72 6e 65 72 20 4b 6f 63 68 20 |ger Werner Koch |
00000060 3c 77 6b 40 67 6e 75 70 67 2e 6f 72 67 3e 20 31 |<wk@gnupg.org> 1|
00000070 35 35 32 39 39 31 38 35 33 20 2b 30 31 30 30 0a |552991853 +0100.|
00000080 0a 4a 75 73 74 20 61 6e 6f 74 68 65 72 20 62 6f |.Just another bo|
00000090 72 69 6e 67 20 72 65 6c 65 61 73 65 0a 04 00 01 |ring release....|
000000a0 08 00 1d 16 21 04 d8 69 21 23 c4 06 5d ea 5e 0f |....!..i!#..].^.|
000000b0 3a b5 24 9b 39 d2 4f 25 e3 b6 05 02 5c 90 c6 6d |:.$.9.O%....\..m|
000000c0 04 ff 00 00 00 23 |.....#|
--8<---------------cut here---------------end--------------->8---

which shows that the tag is actual part of the signed data. There is no
warning if the tag has been renamed because the same data is hashed, we
would expect that from a symlink too and I consider this to be okay.


Salam-Shalom,

Werner


--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.