{"thread":{"id":"64917","subject":"[PATCH v1] gpg-interface: Signatures by expired keys are fine","startedAt":"2026-02-04T15:23:26Z","lastAt":"2026-02-05T09:38:55Z","messageCount":6,"participants":["Uwe Kleine-König","Neal H. Walfield","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"535162","messageId":"20260204152306.1767112-2-ukleinek@kernel.org","threadId":"64917","inReplyTo":null,"subject":"[PATCH v1] gpg-interface: Signatures by expired keys are fine","fromName":"Uwe Kleine-König","fromEmail":"ukleinek@kernel.org","sentAt":"2026-02-04T15:23:06Z","receivedAt":"2026-02-04T15:23:26Z","isPatch":true,"sender":{"key":"ukleinek@kernel.org","avatar":null},"body":"If a signature is done with a valid key and that key later expires, the\nsignature should still be considered good.\n\nGnuPG exmits in this case something like:\n\n\t[GNUPG:] NEWSIG\n\tgpg: Signature made Wed 26 Nov 2014 05:56:50 AM CET\n\tgpg:                using RSA key FE3958F9067BC667\n\t[GNUPG:] KEYEXPIRED 1478449622\n\t[GNUPG:] KEY_CONSIDERED D783920D6D4F0C06AA4C25F3FE3958F9067BC667 0\n\t[GNUPG:] KEYEXPIRED 1478449622\n\t[GNUPG:] SIG_ID 8tAN3Fx6XB2NAoH5U8neoguQ9MI 2014-11-26 1416977810\n\t[GNUPG:] EXPKEYSIG FE3958F9067BC667 Jason Cooper <jason@lakedaemon.net>\n\tgpg: Good signature from \"Jason Cooper <jason@lakedaemon.net>\" [expired]\n\t[GNUPG:] VALIDSIG D783920D6D4F0C06AA4C25F3FE3958F9067BC667 2014-11-26 1416977810 0 4 0 1 2 00 D783920D6D4F0C06AA4C25F3FE3958F9067BC667\n\tgpg: Note: This key has expired!\n\t      D783920D6D4F0C06AA4C25F3FE3958F9067BC667\n\n(signature and signed data in this example is taken from Linux commit\n756f80cee766574ae282baa97fdcf9cc). So GnuPG is relaxed and the fact that\nthe key is expired is only worth a \"Note\" which is weaker than e.g.\n\n\tgpg: WARNING: The key's User ID is not certified with a trusted signature!\n\tgpg:          There is no indication that the signature belongs to the owner.\n\nwhich git still considers ok.\n\nSo stop coloring the signature by an expired key red and handle it like\nany other good signature.\n\nSigned-off-by: Uwe Kleine-König <ukleinek@kernel.org>\n---\nHello,\n\nthe motivation for this patch originates from a mail correspondence with Linus Torvalds,\nsee\nhttps://lore.kernel.org/ksummit/CAHC9VhRwMpSCphW_FsHojX1r12D5MOMUBm6MAzpGYD_FDjEVtA@mail.gmail.com/T/#m6cc3cc4b599658cab6012326993a1261fd641046\nfor the details.\n\nBest regards\nUwe\n\n gpg-interface.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex 47222bf31b6e..6635c6c8e16f 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -382,7 +382,7 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,\n \n \tdelete_tempfile(&temp);\n \n-\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \");\n+\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \") && !strstr(gpg_stdout.buf, \"\\n[GNUPG:] EXPKEYSIG \");\n \tsigc->output = strbuf_detach(&gpg_stderr, NULL);\n \tsigc->gpg_status = strbuf_detach(&gpg_stdout, NULL);\n \n@@ -680,7 +680,7 @@ int check_signature(struct signature_check *sigc,\n \tif (status && !sigc->output)\n \t\treturn !!status;\n \n-\tstatus |= sigc->result != 'G';\n+\tstatus |= sigc->result != 'G' && sigc->result != 'Y';\n \tstatus |= sigc->trust_level < configured_min_trust_level;\n \n \treturn !!status;\n\nbase-commit: b2826b52eb7caff9f4ed6e85ec45e338bf02ad09\n-- \n2.47.3\n\n"},{"id":"535164","messageId":"87fr7g1pz8.wl-neal@walfield.org","threadId":"64917","inReplyTo":"20260204152306.1767112-2-ukleinek@kernel.org","subject":"Re: [PATCH v1] gpg-interface: Signatures by expired keys are fine","fromName":"Neal H. Walfield","fromEmail":"neal@walfield.org","sentAt":"2026-02-04T15:35:23Z","receivedAt":"2026-02-04T16:17:52Z","isPatch":true,"sender":{"key":"neal@walfield.org","avatar":null},"body":"Hi,\n\nI think this change is an improvement over the status quo.  In my\nopinion, a signature should be accepted if it was made when the\ncertificate sas not expired.  If the signature was made after the\ncertificate expired it should be rejected.  That is:\n\n  t_s1: signature 1\n  t_e: certificate expires\n  t_s2: signature 2\n\n  where: t_s1 < t_e < t_s2\n\nsignature 1 should be accepted as t_s1 < t_e.\n\nsignature 2 should be rejected as t_s2 > t_e.\n\nAs GnuPG's interface does not provide enough information to make this\ndistinction, this change is better.\n\n:) Neal\n\nOn Wed, 04 Feb 2026 16:23:06 +0100,\nUwe Kleine-König wrote:\n> \n> If a signature is done with a valid key and that key later expires, the\n> signature should still be considered good.\n> \n> GnuPG exmits in this case something like:\n> \n> \t[GNUPG:] NEWSIG\n> \tgpg: Signature made Wed 26 Nov 2014 05:56:50 AM CET\n> \tgpg:                using RSA key FE3958F9067BC667\n> \t[GNUPG:] KEYEXPIRED 1478449622\n> \t[GNUPG:] KEY_CONSIDERED D783920D6D4F0C06AA4C25F3FE3958F9067BC667 0\n> \t[GNUPG:] KEYEXPIRED 1478449622\n> \t[GNUPG:] SIG_ID 8tAN3Fx6XB2NAoH5U8neoguQ9MI 2014-11-26 1416977810\n> \t[GNUPG:] EXPKEYSIG FE3958F9067BC667 Jason Cooper <jason@lakedaemon.net>\n> \tgpg: Good signature from \"Jason Cooper <jason@lakedaemon.net>\" [expired]\n> \t[GNUPG:] VALIDSIG D783920D6D4F0C06AA4C25F3FE3958F9067BC667 2014-11-26 1416977810 0 4 0 1 2 00 D783920D6D4F0C06AA4C25F3FE3958F9067BC667\n> \tgpg: Note: This key has expired!\n> \t      D783920D6D4F0C06AA4C25F3FE3958F9067BC667\n> \n> (signature and signed data in this example is taken from Linux commit\n> 756f80cee766574ae282baa97fdcf9cc). So GnuPG is relaxed and the fact that\n> the key is expired is only worth a \"Note\" which is weaker than e.g.\n> \n> \tgpg: WARNING: The key's User ID is not certified with a trusted signature!\n> \tgpg:          There is no indication that the signature belongs to the owner.\n> \n> which git still considers ok.\n> \n> So stop coloring the signature by an expired key red and handle it like\n> any other good signature.\n> \n> Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>\n> ---\n> Hello,\n> \n> the motivation for this patch originates from a mail correspondence with Linus Torvalds,\n> see\n> https://lore.kernel.org/ksummit/CAHC9VhRwMpSCphW_FsHojX1r12D5MOMUBm6MAzpGYD_FDjEVtA@mail.gmail.com/T/#m6cc3cc4b599658cab6012326993a1261fd641046\n> for the details.\n> \n> Best regards\n> Uwe\n> \n>  gpg-interface.c | 4 ++--\n>  1 file changed, 2 insertions(+), 2 deletions(-)\n> \n> diff --git a/gpg-interface.c b/gpg-interface.c\n> index 47222bf31b6e..6635c6c8e16f 100644\n> --- a/gpg-interface.c\n> +++ b/gpg-interface.c\n> @@ -382,7 +382,7 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,\n>  \n>  \tdelete_tempfile(&temp);\n>  \n> -\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \");\n> +\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \") && !strstr(gpg_stdout.buf, \"\\n[GNUPG:] EXPKEYSIG \");\n>  \tsigc->output = strbuf_detach(&gpg_stderr, NULL);\n>  \tsigc->gpg_status = strbuf_detach(&gpg_stdout, NULL);\n>  \n> @@ -680,7 +680,7 @@ int check_signature(struct signature_check *sigc,\n>  \tif (status && !sigc->output)\n>  \t\treturn !!status;\n>  \n> -\tstatus |= sigc->result != 'G';\n> +\tstatus |= sigc->result != 'G' && sigc->result != 'Y';\n>  \tstatus |= sigc->trust_level < configured_min_trust_level;\n>  \n>  \treturn !!status;\n> \n> base-commit: b2826b52eb7caff9f4ed6e85ec45e338bf02ad09\n> -- \n> 2.47.3\n> \n> \n"},{"id":"535176","messageId":"xmqqjywspgi6.fsf@gitster.g","threadId":"64917","inReplyTo":"20260204152306.1767112-2-ukleinek@kernel.org","subject":"Re: [PATCH v1] gpg-interface: Signatures by expired keys are fine","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-04T17:26:09Z","receivedAt":"2026-02-04T17:26:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Uwe Kleine-König <ukleinek@kernel.org> writes:\n\n> If a signature is done with a valid key and that key later expires, the\n> signature should still be considered good.\n>\n> GnuPG exmits in this case something like:\n\n\"emits\".\n\n> diff --git a/gpg-interface.c b/gpg-interface.c\n> index 47222bf31b6e..6635c6c8e16f 100644\n> --- a/gpg-interface.c\n> +++ b/gpg-interface.c\n> @@ -382,7 +382,7 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,\n>  \n>  \tdelete_tempfile(&temp);\n>  \n> -\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \");\n> +\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \") && !strstr(gpg_stdout.buf, \"\\n[GNUPG:] EXPKEYSIG \");\n\nMakes sense; I'll wrap this overlong line while queuing, though.\n\n>  \tsigc->output = strbuf_detach(&gpg_stderr, NULL);\n>  \tsigc->gpg_status = strbuf_detach(&gpg_stdout, NULL);\n>  \n> @@ -680,7 +680,7 @@ int check_signature(struct signature_check *sigc,\n>  \tif (status && !sigc->output)\n>  \t\treturn !!status;\n>  \n> -\tstatus |= sigc->result != 'G';\n> +\tstatus |= sigc->result != 'G' && sigc->result != 'Y';\n>  \tstatus |= sigc->trust_level < configured_min_trust_level;\n>  \n>  \treturn !!status;\n>\n> base-commit: b2826b52eb7caff9f4ed6e85ec45e338bf02ad09\n"},{"id":"535192","messageId":"o2xni4463jlbmv226ngrlvepluqm43vg3fsifubanw6unhei77@wwzsa4ciqexw","threadId":"64917","inReplyTo":"xmqqjywspgi6.fsf@gitster.g","subject":"Re: [PATCH v1] gpg-interface: Signatures by expired keys are fine","fromName":"Uwe Kleine-König","fromEmail":"ukleinek@kernel.org","sentAt":"2026-02-04T21:18:08Z","receivedAt":"2026-02-04T21:18:11Z","isPatch":true,"sender":{"key":"ukleinek@kernel.org","avatar":null},"body":"Hello,\n\nOn Wed, Feb 04, 2026 at 09:26:09AM -0800, Junio C Hamano wrote:\n> Uwe Kleine-König <ukleinek@kernel.org> writes:\n> \n> > If a signature is done with a valid key and that key later expires, the\n> > signature should still be considered good.\n> >\n> > GnuPG exmits in this case something like:\n> \n> \"emits\".\n> \n> > diff --git a/gpg-interface.c b/gpg-interface.c\n> > index 47222bf31b6e..6635c6c8e16f 100644\n> > --- a/gpg-interface.c\n> > +++ b/gpg-interface.c\n> > @@ -382,7 +382,7 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,\n> >  \n> >  \tdelete_tempfile(&temp);\n> >  \n> > -\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \");\n> > +\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \") && !strstr(gpg_stdout.buf, \"\\n[GNUPG:] EXPKEYSIG \");\n> \n> Makes sense; I'll wrap this overlong line while queuing, though.\n\nJust to be sure: That means I don't resent with the typo fixed and an\nadditional line break and you care to apply this patch?\n\nThanks\nUwe\n"},{"id":"535194","messageId":"xmqqa4xonqs5.fsf@gitster.g","threadId":"64917","inReplyTo":"o2xni4463jlbmv226ngrlvepluqm43vg3fsifubanw6unhei77@wwzsa4ciqexw","subject":"Re: [PATCH v1] gpg-interface: Signatures by expired keys are fine","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-04T21:27:06Z","receivedAt":"2026-02-04T21:27:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Uwe Kleine-König <ukleinek@kernel.org> writes:\n\n> Hello,\n>\n> On Wed, Feb 04, 2026 at 09:26:09AM -0800, Junio C Hamano wrote:\n>> Uwe Kleine-König <ukleinek@kernel.org> writes:\n>> \n>> > If a signature is done with a valid key and that key later expires, the\n>> > signature should still be considered good.\n>> >\n>> > GnuPG exmits in this case something like:\n>> \n>> \"emits\".\n>> \n>> > diff --git a/gpg-interface.c b/gpg-interface.c\n>> > index 47222bf31b6e..6635c6c8e16f 100644\n>> > --- a/gpg-interface.c\n>> > +++ b/gpg-interface.c\n>> > @@ -382,7 +382,7 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,\n>> >  \n>> >  \tdelete_tempfile(&temp);\n>> >  \n>> > -\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \");\n>> > +\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \") && !strstr(gpg_stdout.buf, \"\\n[GNUPG:] EXPKEYSIG \");\n>> \n>> Makes sense; I'll wrap this overlong line while queuing, though.\n>\n> Just to be sure: That means I don't resent with the typo fixed and an\n> additional line break and you care to apply this patch?\n\nUnless there are other things you want to update, no need to resend.\n\nFYI, here is what I queued.\n\n---- >8 ----\nFrom: Uwe Kleine-König <ukleinek@kernel.org>\nDate: Wed, 4 Feb 2026 16:23:06 +0100\nSubject: [PATCH] gpg-interface: signatures by expired keys are fine\n\nIf a signature is made with a valid key and that key later expires, the\nsignature should still be considered good.\n\nGnuPG emits in this case something like:\n\n\t[GNUPG:] NEWSIG\n\tgpg: Signature made Wed 26 Nov 2014 05:56:50 AM CET\n\tgpg:                using RSA key FE3958F9067BC667\n\t[GNUPG:] KEYEXPIRED 1478449622\n\t[GNUPG:] KEY_CONSIDERED D783920D6D4F0C06AA4C25F3FE3958F9067BC667 0\n\t[GNUPG:] KEYEXPIRED 1478449622\n\t[GNUPG:] SIG_ID 8tAN3Fx6XB2NAoH5U8neoguQ9MI 2014-11-26 1416977810\n\t[GNUPG:] EXPKEYSIG FE3958F9067BC667 Jason Cooper <jason@lakedaemon.net>\n\tgpg: Good signature from \"Jason Cooper <jason@lakedaemon.net>\" [expired]\n\t[GNUPG:] VALIDSIG D783920D6D4F0C06AA4C25F3FE3958F9067BC667 2014-11-26 1416977810 0 4 0 1 2 00 D783920D6D4F0C06AA4C25F3FE3958F9067BC667\n\tgpg: Note: This key has expired!\n\t      D783920D6D4F0C06AA4C25F3FE3958F9067BC667\n\n(signature and signed data in this example is taken from Linux commit\n756f80cee766574ae282baa97fdcf9cc). So GnuPG is relaxed and the fact that\nthe key is expired is only worth a \"Note\" which is weaker than e.g.\n\n\tgpg: WARNING: The key's User ID is not certified with a trusted signature!\n\tgpg:          There is no indication that the signature belongs to the owner.\n\nwhich git still considers ok.\n\nSo stop coloring the signature by an expired key red and handle it like\nany other good signature.\n\nSigned-off-by: Uwe Kleine-König <ukleinek@kernel.org>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n gpg-interface.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex 47222bf31b..5a58f333df 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -382,7 +382,8 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,\n \n \tdelete_tempfile(&temp);\n \n-\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \");\n+\tret |= !strstr(gpg_stdout.buf, \"\\n[GNUPG:] GOODSIG \") &&\n+\t       !strstr(gpg_stdout.buf, \"\\n[GNUPG:] EXPKEYSIG \");\n \tsigc->output = strbuf_detach(&gpg_stderr, NULL);\n \tsigc->gpg_status = strbuf_detach(&gpg_stdout, NULL);\n \n@@ -680,7 +681,7 @@ int check_signature(struct signature_check *sigc,\n \tif (status && !sigc->output)\n \t\treturn !!status;\n \n-\tstatus |= sigc->result != 'G';\n+\tstatus |= sigc->result != 'G' && sigc->result != 'Y';\n \tstatus |= sigc->trust_level < configured_min_trust_level;\n \n \treturn !!status;\n-- \n2.53.0-169-ga09cd4eb64\n\n\n\n"},{"id":"535217","messageId":"lroixebbcfnbr6qcaj5oznvl5c5gwusbzzznev5zllhnta2zj4@zkoypgor7g6e","threadId":"64917","inReplyTo":"xmqqa4xonqs5.fsf@gitster.g","subject":"Re: [PATCH v1] gpg-interface: Signatures by expired keys are fine","fromName":"Uwe Kleine-König","fromEmail":"ukleinek@kernel.org","sentAt":"2026-02-05T09:38:53Z","receivedAt":"2026-02-05T09:38:55Z","isPatch":true,"sender":{"key":"ukleinek@kernel.org","avatar":null},"body":"Hello Junio,\n\nOn Wed, Feb 04, 2026 at 01:27:06PM -0800, Junio C Hamano wrote:\n> Uwe Kleine-König <ukleinek@kernel.org> writes:\n> > On Wed, Feb 04, 2026 at 09:26:09AM -0800, Junio C Hamano wrote:\n> >> Makes sense; I'll wrap this overlong line while queuing, though.\n> >\n> > Just to be sure: That means I don't resent with the typo fixed and an\n> > additional line break and you care to apply this patch?\n> \n> Unless there are other things you want to update, no need to resend.\n> \n> FYI, here is what I queued.\n> \n> ---- >8 ----\n> From: Uwe Kleine-König <ukleinek@kernel.org>\n> Date: Wed, 4 Feb 2026 16:23:06 +0100\n> Subject: [PATCH] gpg-interface: signatures by expired keys are fine\n> \n> [...]\n\nLGTM, thanks!\n\nBest regards\nUwe\n"}]}