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 <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael J Gruber committed
Feb 14, 2013 at 17:04 UTC
b60b7566c04e5f54c0e40229c1716d99d834ab68
1 file changed
+11
-2
gpg-interface.c
+11
-2
@@ -96,15 +96,17 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
96
/*
97
* Run "gpg" to see if the payload matches the detached signature.
98
* gpg_output, when set, receives the diagnostic output from GPG.
99
+ * gpg_status, when set, receives the status output from GPG.
100
*/
101
int verify_signed_buffer(const char *payload, size_t payload_size,
102
const char *signature, size_t signature_size,
103
struct strbuf *gpg_output)
104
{
105
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};
107
char path[PATH_MAX];
108
int fd, ret;
109
+ struct strbuf buf = STRBUF_INIT;
110
111
args_gpg[0] = gpg_program;
112
fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
@@ -119,9 +121,10 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
121
memset(&gpg, 0, sizeof(gpg));
122
gpg.argv = args_gpg;
123
gpg.in = -1;
124
+ gpg.out = -1;
125
if (gpg_output)
126
gpg.err = -1;
124
- args_gpg[2] = path;
127
+ args_gpg[3] = path;
128
if (start_command(&gpg)) {
129
unlink(path);
130
return error("could not run gpg.");
@@ -134,9 +137,15 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
137
strbuf_read(gpg_output, gpg.err, 0);
138
close(gpg.err);
139
}
140
+ strbuf_read(&buf, gpg.out, 0);
141
+ close(gpg.out);
142
+
143
ret = finish_command(&gpg);
144
145
unlink_or_warn(path);
146
147
+ ret |= !strstr(buf.buf, "\n[GNUPG:] GOODSIG ");
148
+ strbuf_release(&buf);
149
+
150
return ret;
151
}