Skip to content

Commit b60b756

Browse files
Michael J Grubergitster
authored andcommitted
gpg-interface: check good signature in a reliable way
Currently, verify_signed_buffer() only checks the return code of gpg, and some callers implement additional unreliable checks for "Good signature" in the gpg output meant for the user. Use the status output instead and parse for a line beinning with "[GNUPG:] GOODSIG ". This is the only reliable way of checking for a good gpg signature. If needed we can change this easily to "[GNUPG:] VALIDSIG " if we want to take into account the trust model. Signed-off-by: Michael J Gruber <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d32805d commit b60b756

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

gpg-interface.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,17 @@ 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,
102103
struct strbuf *gpg_output)
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;
108110

109111
args_gpg[0] = gpg_program;
110112
fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
@@ -119,9 +121,10 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
119121
memset(&gpg, 0, sizeof(gpg));
120122
gpg.argv = args_gpg;
121123
gpg.in = -1;
124+
gpg.out = -1;
122125
if (gpg_output)
123126
gpg.err = -1;
124-
args_gpg[2] = path;
127+
args_gpg[3] = path;
125128
if (start_command(&gpg)) {
126129
unlink(path);
127130
return error("could not run gpg.");
@@ -134,9 +137,15 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
134137
strbuf_read(gpg_output, gpg.err, 0);
135138
close(gpg.err);
136139
}
140+
strbuf_read(&buf, gpg.out, 0);
141+
close(gpg.out);
142+
137143
ret = finish_command(&gpg);
138144

139145
unlink_or_warn(path);
140146

147+
ret |= !strstr(buf.buf, "\n[GNUPG:] GOODSIG ");
148+
strbuf_release(&buf);
149+
141150
return ret;
142151
}

0 commit comments

Comments
 (0)