Git development
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Christian Noé Ramos López" <chris@nortesoftware.dev>
Cc: git@vger.kernel.org,  Phillip Wood <phillip.wood@dunelm.org.uk>,
	Patrick Steinhardt <ps@pks.im>
Subject: Re: [PATCH] gpg-interface: fail when the ssh revocation file is missing
Date: Wed, 21 Oct 2026 11:40:25 -0700	[thread overview]
Message-ID: <xmqqa4o6oq1y.fsf@gitster.g> (raw)
In-Reply-To: <20261021041720.572035-1-chris@nortesoftware.dev> ("Christian Noé Ramos López"'s message of "Wed, 21 Oct 2026 00:17:20 -0400")

Christian Noé Ramos López <chris@nortesoftware.dev> writes:

> diff --git a/gpg-interface.c b/gpg-interface.c
> index 60c315fba..ddbb29e78 100644
> --- a/gpg-interface.c
> +++ b/gpg-interface.c
> @@ -533,6 +533,9 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
>  		 * we still call check-novalidate to display the signature info
>  		 */
>  		ret = -1;
> +	} else if (ssh_revocation_file && !file_exists(ssh_revocation_file)) {
> +		ret = error(_("ssh signing revocation file configured but not found: %s"),
> +			    ssh_revocation_file);
>  	} else {
>  		/* Check every principal we found (one per line) */
>  		const char *next;
> @@ -576,15 +579,9 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
>  				     verify_time.buf,
>  				     NULL);
>  
> -			if (ssh_revocation_file) {
> -				if (file_exists(ssh_revocation_file)) {
> -					strvec_pushl(&ssh_keygen.args, "-r",
> -						     ssh_revocation_file, NULL);
> -				} else {
> -					warning(_("ssh signing revocation file configured but not found: %s"),
> -						ssh_revocation_file);
> -				}
> -			}
> +			if (ssh_revocation_file)
> +				strvec_pushl(&ssh_keygen.args, "-r",
> +					     ssh_revocation_file, NULL);
>  
>  			sigchain_push(SIGPIPE, SIG_IGN);
>  			ret = pipe_command(&ssh_keygen, sigc->payload, sigc->payload_len,

It is a bit hard to see what really goes on with the default
context, so here is an excerpt from "git show -W" output:

> diff --git a/gpg-interface.c b/gpg-interface.c
> index 95abf1ef4e..904165a892 100644
> --- a/gpg-interface.c
> +++ b/gpg-interface.c
> @@ -461,164 +461,161 @@ static void parse_ssh_output(struct signature_check *sigc)
> ...
>  	/* Find the principal from the signers */
>  	strvec_pushl(&ssh_keygen.args, fmt->program,
>  		     "-Y", "find-principals",
>  		     "-f", ssh_allowed_signers,
>  		     "-s", buffer_file->filename.buf,
>  		     verify_time.buf,
>  		     NULL);
>  	ret = pipe_command(&ssh_keygen, NULL, 0, &ssh_principals_out, 0,
>  			   &ssh_principals_err, 0);
>  	if (ret && strstr(ssh_principals_err.buf, "usage:")) {
>  		error(_("ssh-keygen -Y find-principals/verify is needed for ssh signature verification (available in openssh version 8.2p1+)"));
>  		goto out;
>  	}

We asked "-Y find-principals" with allowed_signers file.  There are
a few cases.

>  	if (ret || !ssh_principals_out.len) {
>  		/*
>  		 * We did not find a matching principal in the allowedSigners
>  		 * Check without validation
>  		 */
>  		child_process_init(&ssh_keygen);
>  		strvec_pushl(&ssh_keygen.args, fmt->program,
>  			     "-Y", "check-novalidate",
>  			     "-n", "git",
>  			     "-s", buffer_file->filename.buf,
>  			     verify_time.buf,
>  			     NULL);
>  		pipe_command(&ssh_keygen, sigc->payload, sigc->payload_len,
>  				   &ssh_keygen_out, 0, &ssh_keygen_err, 0);
>  
>  		/*
>  		 * Fail on unknown keys
>  		 * we still call check-novalidate to display the signature info
>  		 */
>  		ret = -1;

If we find that the signature is done with an unknown key, we run
another ssh-keygen with check-validate to show the signature info.

By the way, it is not a problem this patch introduces, but the
comment at the end of this block is a bit misleading.  I first
thought another check-novalidate invocation will happen later in the
function but "we still call" refers to the invocation of ssh-keygen
we just made before the comment.

> +	} else if (ssh_revocation_file && !file_exists(ssh_revocation_file)) {
> +		ret = error(_("ssh signing revocation file configured but not found: %s"),
> +			    ssh_revocation_file);

Inserting the missing revocation file check here means we do not
even give signature information for known keys from this "else if"
block that we would have given for unknown keys in the "if" block,
which is not quite satisfactory.

I wonder if we should be able to somehow fold this into the earlier
"if()" block, making it the single place that deals with failures?

>  	} else {
>  		/* Check every principal we found (one per line) */
>  		const char *next;
>  		for (line = ssh_principals_out.buf;
>  		     *line;
>  		     line = next) {
>  			const char *end_of_text;

And everything we do when we recognise the signing key does not
change, except that ...

>  			/*
>  			 * We found principals
>  			 * Try with each until we find a match
>  			 */
>  			strvec_pushl(&ssh_keygen.args, "-Y", "verify",
>  				     "-n", "git",
>  				     "-f", ssh_allowed_signers,
>  				     "-I", principal,
>  				     "-s", buffer_file->filename.buf,
>  				     verify_time.buf,
>  				     NULL);
>  
> -			if (ssh_revocation_file) {
> -				if (file_exists(ssh_revocation_file)) {
> -					strvec_pushl(&ssh_keygen.args, "-r",
> -						     ssh_revocation_file, NULL);
> -				} else {
> -					warning(_("ssh signing revocation file configured but not found: %s"),
> -						ssh_revocation_file);
> -				}
> -			}
> +			if (ssh_revocation_file)
> +				strvec_pushl(&ssh_keygen.args, "-r",
> +					     ssh_revocation_file, NULL);

... we no longer need to see if the file is missing, which makes sense.

      reply	other threads:[~2026-10-21 18:40 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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
2026-10-21  3:03   ` [PATCH] doc: gpg: say which date SSH key lifetimes are checked against Christian Noé Ramos López
2026-10-21 18:14     ` Junio C Hamano
2026-10-21  4:17   ` [PATCH] gpg-interface: fail when the ssh revocation file is missing Christian Noé Ramos López
2026-10-21 18:40     ` Junio C Hamano [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqa4o6oq1y.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=chris@nortesoftware.dev \
    --cc=git@vger.kernel.org \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox