Git development
 help / color / mirror / Atom feed
* ssh signing: valid-before is checked at the signer's own date, and a missing revocationFile fails open
@ 2026-10-08  6:56 Christian Noé Ramos López
  2026-10-08 13:42 ` Phillip Wood
  0 siblings, 1 reply; 5+ messages in thread
From: Christian Noé Ramos López @ 2026-10-08  6:56 UTC (permalink / raw)
  To: git

Two things that, together, mean an SSH signing key cannot be reliably
stopped from being trusted. git 2.47.3, OpenSSH 10.0p2, Debian 13;
source read at v2.47.3 and at master (c46c1e37724f).

1. valid-before is checked at a date the signer writes.

SSH signatures carry no time of their own, so git passes -Overify-time
from the committer or tagger line (gpg-interface.c,
parse_payload_metadata). alice's key is in the allowed signers file
with valid-before="20260101":

    ssh-old        %G?=G 2025-06-01 12:00:00 +0000 verify-commit=0 merge=0
    ssh-backdated  %G?=G 2025-06-01 12:00:00 +0000 verify-commit=0 merge=0
    ssh-honest     %G?=U 2026-10-08 02:15:15 -0400 verify-commit=1 merge=128

ssh-backdated was signed today, with only the committer and author
dates set to 2025-06-01. Nothing distinguishes it from ssh-old except
when it was made, which only its author knows. ssh-honest, signed and
dated today, is refused: "key has expired: verify time ... >
valid-before 2026-01-01T00:00:00".

The GPG backend refuses both:

    gpg-old        %G?=Y verify-commit=1 merge=128
    gpg-backdated  %G?=Y verify-commit=1 merge=128

The documentation for gpg.ssh.allowedSignersFile says "Git will mark
signatures as valid if the signing key was valid at the time of the
signature's creation", which is the intent, but does not say the time
comes from the commit. So valid-before rotates a key; it does not
retire one.

2. A configured revocation file that does not exist fails open.

gpg-interface.c:568-574 at v2.47.3 (579-586 at master): if the
revocation file exists, pass -r; otherwise warn and verify without it.
The same file, present and listing alice's key, refuses:

    S2-revoked       %G?=B verify-commit=1 merged=no
    S3-revfile-gone  %G?=G verify-commit=0 merged=yes
                     warning: ssh signing revocation file configured
but not found

S3 merged under `git merge --ff-only --verify-signatures`. An
unreadable file and a directory both fail closed:

    S4-revfile-0000  %G?=B verify-commit=1 merged=no
    S6-revfile-dir   %G?=B verify-commit=1 merged=no

ssh-keygen, given the same missing path, refuses: exit 255, "Could not
verify signature". git avoids that by not passing -r. OpenSSH's
RevokedKeys says, in sshd_config(5), "Note that if this file is not
readable, then public key authentication will be refused for all
users."

No test in git exercises gpg.ssh.revocationFile; it appears only in
Documentation/config/gpg.adoc and gpg-interface.c.

Controls for both runs, fixed beforehand: a good signature gives G and
merges; an unsigned commit gives N and is refused; the revocation file
present and listing the key gives B and is refused; a commit with its
message changed and the signature kept gives B and is refused.

Together: the two ways to stop trusting an SSH signing key are
valid-before, which the signer can date around, and revocationFile,
which does nothing if its path is wrong. Either would be enough on its
own if it held.

What I would ask for: refuse when the revocation file is configured and
missing, as ssh-keygen and sshd do, or say in the documentation that it
is ignored; and say, under valid-before, where the time compared
against it comes from.

On prior art: the ssh signing series (Fabian Stelzer, 2021) carried the
warning from before v4, and the review raised the config name's case,
not what a missing file should do. The key-lifetime series (RFC
2021-10-15 to v6 2021-12-09) passes the commit date to the check, and
the replies are about style. The N for an unconfigured allowed signers
file is already on the list (Grayson Tinker, 2026-06-25) and is not
part of this.

Christian Ramos
Norte Software
chris@nortesoftware.dev

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-09 13:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08  6:56 ssh signing: valid-before is checked at the signer's own date, and a missing revocationFile fails open Christian Noé Ramos López
2026-10-08 13:42 ` Phillip Wood
2026-10-09 12:19   ` Patrick Steinhardt
2026-10-09 13:30     ` Phillip Wood
     [not found]   ` <CAHGSfba9Td+Lg=Nf+nfwZY2r1_eq2Mcejn__6X=VPQkmcJttfQ@mail.gmail.com>
2026-10-09 13:29     ` Phillip Wood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox