Skip to content

Commit 0f6875d

Browse files
committed
Merge branch 'mg/gpg-interface-using-status'
Call "gpg" using the right API when validating the signature on tags. * mg/gpg-interface-using-status: pretty: make %GK output the signing key for signed commits pretty: parse the gpg status lines rather than the output gpg_interface: allow to request status return log-tree: rely upon the check in the gpg_interface gpg-interface: check good signature in a reliable way
2 parents dcf0d12 + 0174eea commit 0f6875d

File tree

7 files changed

+46
-25
lines changed

7 files changed

+46
-25
lines changed

Documentation/pretty-formats.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ The placeholders are:
133133
- '%GG': raw verification message from GPG for a signed commit
134134
- '%G?': show either "G" for Good or "B" for Bad for a signed commit
135135
- '%GS': show the name of the signer for a signed commit
136+
- '%GK': show the key used to sign a signed commit
136137
- '%gD': reflog selector, e.g., `refs/stash@{1}`
137138
- '%gd': shortened reflog selector, e.g., `stash@{1}`
138139
- '%gn': reflog identity name

builtin/fmt-merge-msg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
492492

493493
if (size == len)
494494
; /* merely annotated */
495-
else if (verify_signed_buffer(buf, len, buf + len, size - len, &sig)) {
495+
else if (verify_signed_buffer(buf, len, buf + len, size - len, &sig, NULL)) {
496496
if (!sig.len)
497497
strbuf_addstr(&sig, "gpg verification failed.\n");
498498
}

builtin/verify-tag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
2929
if (size == len)
3030
return error("no signature found");
3131

32-
return verify_signed_buffer(buf, len, buf + len, size - len, NULL);
32+
return verify_signed_buffer(buf, len, buf + len, size - len, NULL, NULL);
3333
}
3434

3535
static int verify_tag(const char *name, int verbose)

gpg-interface.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,18 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
9696
/*
9797
* Run "gpg" to see if the payload matches the detached signature.
9898
* gpg_output, when set, receives the diagnostic output from GPG.
99+
* gpg_status, when set, receives the status output from GPG.
99100
*/
100101
int verify_signed_buffer(const char *payload, size_t payload_size,
101102
const char *signature, size_t signature_size,
102-
struct strbuf *gpg_output)
103+
struct strbuf *gpg_output, struct strbuf *gpg_status)
103104
{
104105
struct child_process gpg;
105-
const char *args_gpg[] = {NULL, "--verify", "FILE", "-", NULL};
106+
const char *args_gpg[] = {NULL, "--status-fd=1", "--verify", "FILE", "-", NULL};
106107
char path[PATH_MAX];
107108
int fd, ret;
109+
struct strbuf buf = STRBUF_INIT;
110+
struct strbuf *pbuf = &buf;
108111

109112
args_gpg[0] = gpg_program;
110113
fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
@@ -119,9 +122,10 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
119122
memset(&gpg, 0, sizeof(gpg));
120123
gpg.argv = args_gpg;
121124
gpg.in = -1;
125+
gpg.out = -1;
122126
if (gpg_output)
123127
gpg.err = -1;
124-
args_gpg[2] = path;
128+
args_gpg[3] = path;
125129
if (start_command(&gpg)) {
126130
unlink(path);
127131
return error(_("could not run gpg."));
@@ -134,9 +138,17 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
134138
strbuf_read(gpg_output, gpg.err, 0);
135139
close(gpg.err);
136140
}
141+
if (gpg_status)
142+
pbuf = gpg_status;
143+
strbuf_read(pbuf, gpg.out, 0);
144+
close(gpg.out);
145+
137146
ret = finish_command(&gpg);
138147

139148
unlink_or_warn(path);
140149

150+
ret |= !strstr(pbuf->buf, "\n[GNUPG:] GOODSIG ");
151+
strbuf_release(&buf); /* no matter it was used or not */
152+
141153
return ret;
142154
}

gpg-interface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define GPG_INTERFACE_H
33

44
extern int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key);
5-
extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output);
5+
extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status);
66
extern int git_gpg_config(const char *, const char *, void *);
77
extern void set_signing_key(const char *);
88
extern const char *get_signing_key(void);

log-tree.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ static void show_signature(struct rev_info *opt, struct commit *commit)
444444

445445
status = verify_signed_buffer(payload.buf, payload.len,
446446
signature.buf, signature.len,
447-
&gpg_output);
447+
&gpg_output, NULL);
448448
if (status && !gpg_output.len)
449449
strbuf_addstr(&gpg_output, "No signature\n");
450450

@@ -508,20 +508,17 @@ static void show_one_mergetag(struct rev_info *opt,
508508
gpg_message_offset = verify_message.len;
509509

510510
payload_size = parse_signature(extra->value, extra->len);
511-
if ((extra->len <= payload_size) ||
512-
(verify_signed_buffer(extra->value, payload_size,
513-
extra->value + payload_size,
514-
extra->len - payload_size,
515-
&verify_message) &&
516-
verify_message.len <= gpg_message_offset)) {
517-
strbuf_addstr(&verify_message, "No signature\n");
518-
status = -1;
519-
}
520-
else if (strstr(verify_message.buf + gpg_message_offset,
521-
": Good signature from "))
522-
status = 0;
523-
else
524-
status = -1;
511+
status = -1;
512+
if (extra->len > payload_size)
513+
if (verify_signed_buffer(extra->value, payload_size,
514+
extra->value + payload_size,
515+
extra->len - payload_size,
516+
&verify_message, NULL)) {
517+
if (verify_message.len <= gpg_message_offset)
518+
strbuf_addstr(&verify_message, "No signature\n");
519+
else
520+
status = 0;
521+
}
525522

526523
show_sig_lines(opt, status, verify_message.buf);
527524
strbuf_release(&verify_message);

pretty.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -759,8 +759,10 @@ struct format_commit_context {
759759
unsigned commit_signature_parsed:1;
760760
struct {
761761
char *gpg_output;
762+
char *gpg_status;
762763
char good_bad;
763764
char *signer;
765+
char *key;
764766
} signature;
765767
char *message;
766768
size_t width, indent1, indent2;
@@ -948,13 +950,13 @@ static struct {
948950
char result;
949951
const char *check;
950952
} signature_check[] = {
951-
{ 'G', ": Good signature from " },
952-
{ 'B', ": BAD signature from " },
953+
{ 'G', "\n[GNUPG:] GOODSIG " },
954+
{ 'B', "\n[GNUPG:] BADSIG " },
953955
};
954956

955957
static void parse_signature_lines(struct format_commit_context *ctx)
956958
{
957-
const char *buf = ctx->signature.gpg_output;
959+
const char *buf = ctx->signature.gpg_status;
958960
int i;
959961

960962
for (i = 0; i < ARRAY_SIZE(signature_check); i++) {
@@ -964,6 +966,8 @@ static void parse_signature_lines(struct format_commit_context *ctx)
964966
continue;
965967
ctx->signature.good_bad = signature_check[i].result;
966968
found += strlen(signature_check[i].check);
969+
ctx->signature.key = xmemdupz(found, 16);
970+
found += 17;
967971
next = strchrnul(found, '\n');
968972
ctx->signature.signer = xmemdupz(found, next - found);
969973
break;
@@ -975,6 +979,7 @@ static void parse_commit_signature(struct format_commit_context *ctx)
975979
struct strbuf payload = STRBUF_INIT;
976980
struct strbuf signature = STRBUF_INIT;
977981
struct strbuf gpg_output = STRBUF_INIT;
982+
struct strbuf gpg_status = STRBUF_INIT;
978983
int status;
979984

980985
ctx->commit_signature_parsed = 1;
@@ -984,13 +989,15 @@ static void parse_commit_signature(struct format_commit_context *ctx)
984989
goto out;
985990
status = verify_signed_buffer(payload.buf, payload.len,
986991
signature.buf, signature.len,
987-
&gpg_output);
992+
&gpg_output, &gpg_status);
988993
if (status && !gpg_output.len)
989994
goto out;
990995
ctx->signature.gpg_output = strbuf_detach(&gpg_output, NULL);
996+
ctx->signature.gpg_status = strbuf_detach(&gpg_status, NULL);
991997
parse_signature_lines(ctx);
992998

993999
out:
1000+
strbuf_release(&gpg_status);
9941001
strbuf_release(&gpg_output);
9951002
strbuf_release(&payload);
9961003
strbuf_release(&signature);
@@ -1200,6 +1207,10 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
12001207
if (c->signature.signer)
12011208
strbuf_addstr(sb, c->signature.signer);
12021209
break;
1210+
case 'K':
1211+
if (c->signature.key)
1212+
strbuf_addstr(sb, c->signature.key);
1213+
break;
12031214
}
12041215
return 2;
12051216
}

0 commit comments

Comments
 (0)