Revert "gpg-interface: prefer check_signature() for GPG verification"
This reverts commit 72b006f4bf
, which
breaks the end-user experience when merging a signed tag without
having the public key. We should report "can't check because we
have no public key", but the code with this change claimed that
there was no signature.
This commit is contained in:
parent
72b006f4bf
commit
0106b1d4be
@ -495,7 +495,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)
|
||||
@ -504,12 +503,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
|
||||
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);
|
||||
|
@ -207,55 +207,6 @@ found_duplicate_status:
|
||||
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)
|
||||
{
|
||||
@ -400,3 +351,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;
|
||||
}
|
||||
|
@ -46,6 +46,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);
|
||||
|
28
log-tree.c
28
log-tree.c
@ -448,22 +448,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);
|
||||
}
|
||||
@ -496,7 +496,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;
|
||||
|
||||
@ -525,13 +524,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,
|
||||
if (!verify_signed_buffer(extra->value, payload_size,
|
||||
extra->value + payload_size,
|
||||
extra->len - payload_size, &sigc)) {
|
||||
strbuf_addstr(&verify_message, sigc.gpg_output);
|
||||
signature_check_clear(&sigc);
|
||||
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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user