Re: gpg.ssh.defaultKeyCommand docs bug?
- From
Jeff King <peff@peff.net>
- Date
- Oct 9, 2023, 20:43 UTC
- Message-ID
- <20231009204341.GB3281325@coredump.intra.peff.net>
- In-Reply-To
- <CAHKF-AvUxH1Ar3Xijjb4_8N+_kssPHZVHqQSAE9kDGRfTYHyxw@mail.gmail.com>
[+cc Fabian, who wrote this code]
On Fri, Oct 06, 2023 at 01:14:49PM -0400, matthew sporleder wrote:
Show 25 quoted lines
> https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgsshdefaultKeyCommand
>
> This command that will be run when user.signingkey is not set and a
> ssh signature is requested. On successful exit a valid ssh public key
> prefixed with key:: is expected in the first line of its output. This
> allows for a script doing a dynamic lookup of the correct public key
> when it is impractical to statically configure user.signingKey. For
> example when keys or SSH Certificates are rotated frequently or
> selection of the right key depends on external factors unknown to git.
>
> ---
>
> The command does not actually work (for me, git version 2.42.0) with
> key:: prefixed.
>
> It only works if I cat the public key as-is.
>
> I only figured this out because the docs previously said it took the
> format of ssh-add -L, which also doesn't not contain key::.
>
> I am using this script for my "dynamic" key discovery:
> #!/bin/sh
> f=$(ssh -G $(git remote get-url $(git remote|head -1)|awk -F':' '{
> print $1 }') |grep -E '^identityfile'|sed 's#^identityfile ##g')
> cat $(eval realpath ${f}.pub)I'm not very familiar with this part of Git, but looking at the code which parses the output of gpg.ssh.defaultKeyCommand, it splits it by line and then calls is_literal_ssh_key() on it, which is:
static int is_literal_ssh_key(const char *string, const char **key)
{
if (skip_prefix(string, "key::", key))
return 1;
if (starts_with(string, "ssh-")) {
*key = string;
return 1;
}
return 0;
}So your script works because the pub file starts with "ssh-rsa" or similar (and so would "ssh-add -L" output).
The user.signingKey docs say:
For backward compatibility, a raw key which begins with "ssh-", such as "ssh-rsa XXXXXX identifier", is treated as "key::ssh-rsa XXXXXX identifier", but this form is deprecated; use the key:: form instead.
From reading the commit messages here, I guess this is about supporting non-ssh key types (e.g., my TPM-based key is ecdsa-sha2-nistp256 in the "ssh-add -L" output). But I'm not sure who is supposed to be put "key::" there.
You said it "does not actually work" with "key::" prefixed. What happens? In the signing code we make a similar call to is_literal_ssh_key() that wills trip off the "key::" prefix, so I'd expect it work. But I could also believe there is a bug. :)
-Peff