A previous commit extracted the hash algorithm from GPG/GPGSM signature status output and stored it in a new 'sig_algo' member of 'struct signature_check'. For SSH signatures, it's more interesting and easier to extract the key type (like "RSA", "ECDSA", "Ed25519", ...) rather than the hash algorithm which often depends on the key type. For example "Ed25519" has SHA-512 integrated into its design, and "ECDSA" and "RSA" are typically used with SHA-256. Let's improve the `gpg-interface` parsing logic to capture the SSH key type when parsing the SSH signature status output. Similarly as the hash algorithm for GPG/GPGSM signatures, this information can be useful for Git commands or external tools that process signature information. For example, it could be used when displaying signature verification results to users or when working with various signature formats in tools like fast-export and fast-import. As they share a common usage, we also store the SSH key type in the new 'sig_algo' member of 'struct signature_check'. Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx> --- gpg-interface.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/gpg-interface.c b/gpg-interface.c index 15687ede43..182e579769 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -456,11 +456,27 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc, return ret; } +static char *extract_ssh_key_type(const char *type_start, const char *type_end) +{ + if (!type_end || type_end <= type_start) + return NULL; + + /* Back up over any spaces before " key " */ + while (type_end > type_start && *(type_end - 1) == ' ') + type_end--; + + if (type_end <= type_start) + return NULL; + + return xmemdupz(type_start, type_end - type_start); +} + static void parse_ssh_output(struct signature_check *sigc) { const char *line, *principal, *search; char *to_free; char *key = NULL; + const char *after_last_with = NULL; /* * ssh-keygen output should be: @@ -485,8 +501,10 @@ static void parse_ssh_output(struct signature_check *sigc) principal = line; do { search = strstr(line, " with "); - if (search) + if (search) { line = search + 1; + after_last_with = search + 6; + } } while (search != NULL); if (line == principal) goto cleanup; @@ -499,6 +517,7 @@ static void parse_ssh_output(struct signature_check *sigc) /* Valid signature, but key unknown */ sigc->result = 'G'; sigc->trust_level = TRUST_UNDEFINED; + after_last_with = line; } else { goto cleanup; } @@ -507,6 +526,9 @@ static void parse_ssh_output(struct signature_check *sigc) if (key) { sigc->fingerprint = xstrdup(key + 4); sigc->key = xstrdup(sigc->fingerprint); + + if (after_last_with) + sigc->sig_algo = extract_ssh_key_type(after_last_with, key); } else { /* * Output did not match what we expected -- 2.49.0.609.g63c55177e5