summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-03-05 10:43:05 -0800
committerJunio C Hamano <gitster@pobox.com>2020-03-05 10:43:05 -0800
commite63cefb024895fcff4b692cad84cb33ac4c81dcc (patch)
tree75658b419b1a097b7bdce369262361323e6c8b7e
parent5da7329e29db93a93099bfee2a81171392341ac8 (diff)
parent0106b1d4be166fd4f7bcf0b901d50940c9f539e2 (diff)
downloadgit-e63cefb024895fcff4b692cad84cb33ac4c81dcc.tar.gz
Merge branch 'hi/gpg-use-check-signature'
"git merge signed-tag" while lacking the public key started to say "No signature", which was utterly wrong. This regression has been reverted. * hi/gpg-use-check-signature: Revert "gpg-interface: prefer check_signature() for GPG verification"
-rw-r--r--builtin/fmt-merge-msg.c11
-rw-r--r--gpg-interface.c97
-rw-r--r--gpg-interface.h9
-rw-r--r--log-tree.c30
4 files changed, 75 insertions, 72 deletions
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 05a92c59d8..736f666f64 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -494,7 +494,6 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
enum object_type type;
unsigned long size, len;
char *buf = read_object_file(oid, &type, &size);
- struct signature_check sigc = { 0 };
struct strbuf sig = STRBUF_INIT;
if (!buf || type != OBJ_TAG)
@@ -503,12 +502,10 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
if (size == len)
; /* merely annotated */
- else if (!check_signature(buf, len, buf + len, size - len,
- &sigc)) {
- strbuf_addstr(&sig, sigc.gpg_output);
- signature_check_clear(&sigc);
- } else
- strbuf_addstr(&sig, "gpg verification failed.\n");
+ else if (verify_signed_buffer(buf, len, buf + len, size - len, &sig, NULL)) {
+ if (!sig.len)
+ strbuf_addstr(&sig, "gpg verification failed.\n");
+ }
if (!tag_number++) {
fmt_tag_signature(&tagbuf, &sig, buf, len);
diff --git a/gpg-interface.c b/gpg-interface.c
index 2d538bcd6e..165274d74a 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -256,55 +256,6 @@ error:
FREE_AND_NULL(sigc->key);
}
-static 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)
-{
- struct child_process gpg = CHILD_PROCESS_INIT;
- struct gpg_format *fmt;
- struct tempfile *temp;
- int ret;
- struct strbuf buf = STRBUF_INIT;
-
- temp = mks_tempfile_t(".git_vtag_tmpXXXXXX");
- if (!temp)
- return error_errno(_("could not create temporary file"));
- if (write_in_full(temp->fd, signature, signature_size) < 0 ||
- close_tempfile_gently(temp) < 0) {
- error_errno(_("failed writing detached signature to '%s'"),
- temp->filename.buf);
- delete_tempfile(&temp);
- return -1;
- }
-
- fmt = get_format_by_sig(signature);
- if (!fmt)
- BUG("bad signature '%s'", signature);
-
- argv_array_push(&gpg.args, fmt->program);
- argv_array_pushv(&gpg.args, fmt->verify_args);
- argv_array_pushl(&gpg.args,
- "--status-fd=1",
- "--verify", temp->filename.buf, "-",
- NULL);
-
- if (!gpg_status)
- gpg_status = &buf;
-
- sigchain_push(SIGPIPE, SIG_IGN);
- ret = pipe_command(&gpg, payload, payload_size,
- gpg_status, 0, gpg_output, 0);
- sigchain_pop(SIGPIPE);
-
- delete_tempfile(&temp);
-
- ret |= !strstr(gpg_status->buf, "\n[GNUPG:] GOODSIG ");
- strbuf_release(&buf); /* no matter it was used or not */
-
- return ret;
-}
-
int check_signature(const char *payload, size_t plen, const char *signature,
size_t slen, struct signature_check *sigc)
{
@@ -467,3 +418,51 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
return 0;
}
+
+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)
+{
+ struct child_process gpg = CHILD_PROCESS_INIT;
+ struct gpg_format *fmt;
+ struct tempfile *temp;
+ int ret;
+ struct strbuf buf = STRBUF_INIT;
+
+ temp = mks_tempfile_t(".git_vtag_tmpXXXXXX");
+ if (!temp)
+ return error_errno(_("could not create temporary file"));
+ if (write_in_full(temp->fd, signature, signature_size) < 0 ||
+ close_tempfile_gently(temp) < 0) {
+ error_errno(_("failed writing detached signature to '%s'"),
+ temp->filename.buf);
+ delete_tempfile(&temp);
+ return -1;
+ }
+
+ fmt = get_format_by_sig(signature);
+ if (!fmt)
+ BUG("bad signature '%s'", signature);
+
+ argv_array_push(&gpg.args, fmt->program);
+ argv_array_pushv(&gpg.args, fmt->verify_args);
+ argv_array_pushl(&gpg.args,
+ "--status-fd=1",
+ "--verify", temp->filename.buf, "-",
+ NULL);
+
+ if (!gpg_status)
+ gpg_status = &buf;
+
+ sigchain_push(SIGPIPE, SIG_IGN);
+ ret = pipe_command(&gpg, payload, payload_size,
+ gpg_status, 0, gpg_output, 0);
+ sigchain_pop(SIGPIPE);
+
+ delete_tempfile(&temp);
+
+ ret |= !strstr(gpg_status->buf, "\n[GNUPG:] GOODSIG ");
+ strbuf_release(&buf); /* no matter it was used or not */
+
+ return ret;
+}
diff --git a/gpg-interface.h b/gpg-interface.h
index f4e9b4f371..796571e9e9 100644
--- a/gpg-interface.h
+++ b/gpg-interface.h
@@ -54,6 +54,15 @@ size_t parse_signature(const char *buf, size_t size);
int sign_buffer(struct strbuf *buffer, struct strbuf *signature,
const char *signing_key);
+/*
+ * Run "gpg" to see if the payload matches the detached signature.
+ * gpg_output, when set, receives the diagnostic output from GPG.
+ * gpg_status, when set, receives the status output from GPG.
+ */
+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);
+
int git_gpg_config(const char *, const char *, void *);
void set_signing_key(const char *);
const char *get_signing_key(void);
diff --git a/log-tree.c b/log-tree.c
index cae38dcc66..5425ae931f 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -449,22 +449,22 @@ static void show_signature(struct rev_info *opt, struct commit *commit)
{
struct strbuf payload = STRBUF_INIT;
struct strbuf signature = STRBUF_INIT;
- struct signature_check sigc = { 0 };
+ struct strbuf gpg_output = STRBUF_INIT;
int status;
if (parse_signed_commit(commit, &payload, &signature) <= 0)
goto out;
- status = check_signature(payload.buf, payload.len, signature.buf,
- signature.len, &sigc);
- if (status && sigc.result == 'N')
- show_sig_lines(opt, status, "No signature\n");
- else {
- show_sig_lines(opt, status, sigc.gpg_output);
- signature_check_clear(&sigc);
- }
+ status = verify_signed_buffer(payload.buf, payload.len,
+ signature.buf, signature.len,
+ &gpg_output, NULL);
+ if (status && !gpg_output.len)
+ strbuf_addstr(&gpg_output, "No signature\n");
+
+ show_sig_lines(opt, status, gpg_output.buf);
out:
+ strbuf_release(&gpg_output);
strbuf_release(&payload);
strbuf_release(&signature);
}
@@ -497,7 +497,6 @@ static int show_one_mergetag(struct commit *commit,
struct object_id oid;
struct tag *tag;
struct strbuf verify_message;
- struct signature_check sigc = { 0 };
int status, nth;
size_t payload_size, gpg_message_offset;
@@ -527,13 +526,12 @@ static int show_one_mergetag(struct commit *commit,
status = -1;
if (extra->len > payload_size) {
/* could have a good signature */
- if (!check_signature(extra->value, payload_size,
- extra->value + payload_size,
- extra->len - payload_size, &sigc)) {
- strbuf_addstr(&verify_message, sigc.gpg_output);
- signature_check_clear(&sigc);
+ if (!verify_signed_buffer(extra->value, payload_size,
+ extra->value + payload_size,
+ extra->len - payload_size,
+ &verify_message, NULL))
status = 0; /* good */
- } else if (verify_message.len <= gpg_message_offset)
+ else if (verify_message.len <= gpg_message_offset)
strbuf_addstr(&verify_message, "No signature\n");
/* otherwise we couldn't verify, which is shown as bad */
}