gpg: centralize signature check
verify-commit and verify-tag both share a central codepath for verifying commits: check_signature. However, verify-tag exited successfully for untrusted signature, while verify-commit exited unsuccessfully. Centralize this signature check and make verify-commit adopt the older verify-tag behavior. This behavior is more logical anyway, as the signature is in fact valid, whether or not there's a path of trust to the author. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
8e98e5f27a
commit
434060ec6d
@ -21,10 +21,11 @@ static const char * const verify_commit_usage[] = {
|
|||||||
static int run_gpg_verify(const unsigned char *sha1, const char *buf, unsigned long size, int verbose)
|
static int run_gpg_verify(const unsigned char *sha1, const char *buf, unsigned long size, int verbose)
|
||||||
{
|
{
|
||||||
struct signature_check signature_check;
|
struct signature_check signature_check;
|
||||||
|
int ret;
|
||||||
|
|
||||||
memset(&signature_check, 0, sizeof(signature_check));
|
memset(&signature_check, 0, sizeof(signature_check));
|
||||||
|
|
||||||
check_commit_signature(lookup_commit(sha1), &signature_check);
|
ret = check_commit_signature(lookup_commit(sha1), &signature_check);
|
||||||
|
|
||||||
if (verbose && signature_check.payload)
|
if (verbose && signature_check.payload)
|
||||||
fputs(signature_check.payload, stdout);
|
fputs(signature_check.payload, stdout);
|
||||||
@ -33,7 +34,7 @@ static int run_gpg_verify(const unsigned char *sha1, const char *buf, unsigned l
|
|||||||
fputs(signature_check.gpg_output, stderr);
|
fputs(signature_check.gpg_output, stderr);
|
||||||
|
|
||||||
signature_check_clear(&signature_check);
|
signature_check_clear(&signature_check);
|
||||||
return signature_check.result != 'G';
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int verify_commit(const char *name, int verbose)
|
static int verify_commit(const char *name, int verbose)
|
||||||
|
@ -22,6 +22,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
|
|||||||
{
|
{
|
||||||
struct signature_check sigc;
|
struct signature_check sigc;
|
||||||
int len;
|
int len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
memset(&sigc, 0, sizeof(sigc));
|
memset(&sigc, 0, sizeof(sigc));
|
||||||
|
|
||||||
@ -32,11 +33,11 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
|
|||||||
if (size == len)
|
if (size == len)
|
||||||
return error("no signature found");
|
return error("no signature found");
|
||||||
|
|
||||||
check_signature(buf, len, buf + len, size - len, &sigc);
|
ret = check_signature(buf, len, buf + len, size - len, &sigc);
|
||||||
fputs(sigc.gpg_output, stderr);
|
fputs(sigc.gpg_output, stderr);
|
||||||
|
|
||||||
signature_check_clear(&sigc);
|
signature_check_clear(&sigc);
|
||||||
return sigc.result != 'G' && sigc.result != 'U';
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int verify_tag(const char *name, int verbose)
|
static int verify_tag(const char *name, int verbose)
|
||||||
|
8
commit.c
8
commit.c
@ -1227,20 +1227,24 @@ free_return:
|
|||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_commit_signature(const struct commit *commit, struct signature_check *sigc)
|
int check_commit_signature(const struct commit *commit, struct signature_check *sigc)
|
||||||
{
|
{
|
||||||
struct strbuf payload = STRBUF_INIT;
|
struct strbuf payload = STRBUF_INIT;
|
||||||
struct strbuf signature = STRBUF_INIT;
|
struct strbuf signature = STRBUF_INIT;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
sigc->result = 'N';
|
sigc->result = 'N';
|
||||||
|
|
||||||
if (parse_signed_commit(commit, &payload, &signature) <= 0)
|
if (parse_signed_commit(commit, &payload, &signature) <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
check_signature(payload.buf, payload.len, signature.buf, signature.len, sigc);
|
ret = check_signature(payload.buf, payload.len, signature.buf,
|
||||||
|
signature.len, sigc);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
strbuf_release(&payload);
|
strbuf_release(&payload);
|
||||||
strbuf_release(&signature);
|
strbuf_release(&signature);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
2
commit.h
2
commit.h
@ -375,7 +375,7 @@ extern void print_commit_list(struct commit_list *list,
|
|||||||
* at all. This may allocate memory for sig->gpg_output, sig->gpg_status,
|
* at all. This may allocate memory for sig->gpg_output, sig->gpg_status,
|
||||||
* sig->signer and sig->key.
|
* sig->signer and sig->key.
|
||||||
*/
|
*/
|
||||||
extern void check_commit_signature(const struct commit *commit, struct signature_check *sigc);
|
extern int check_commit_signature(const struct commit *commit, struct signature_check *sigc);
|
||||||
|
|
||||||
int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);
|
int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ void parse_gpg_output(struct signature_check *sigc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_signature(const char *payload, size_t plen, const char *signature,
|
int check_signature(const char *payload, size_t plen, const char *signature,
|
||||||
size_t slen, struct signature_check *sigc)
|
size_t slen, struct signature_check *sigc)
|
||||||
{
|
{
|
||||||
struct strbuf gpg_output = STRBUF_INIT;
|
struct strbuf gpg_output = STRBUF_INIT;
|
||||||
@ -81,6 +81,8 @@ void check_signature(const char *payload, size_t plen, const char *signature,
|
|||||||
out:
|
out:
|
||||||
strbuf_release(&gpg_status);
|
strbuf_release(&gpg_status);
|
||||||
strbuf_release(&gpg_output);
|
strbuf_release(&gpg_output);
|
||||||
|
|
||||||
|
return sigc->result != 'G' && sigc->result != 'U';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -27,7 +27,7 @@ extern int verify_signed_buffer(const char *payload, size_t payload_size, const
|
|||||||
extern int git_gpg_config(const char *, const char *, void *);
|
extern int git_gpg_config(const char *, const char *, void *);
|
||||||
extern void set_signing_key(const char *);
|
extern void set_signing_key(const char *);
|
||||||
extern const char *get_signing_key(void);
|
extern const char *get_signing_key(void);
|
||||||
extern void check_signature(const char *payload, size_t plen,
|
extern int check_signature(const char *payload, size_t plen,
|
||||||
const char *signature, size_t slen, struct signature_check *sigc);
|
const char *signature, size_t slen, struct signature_check *sigc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,7 +81,7 @@ test_expect_success GPG 'verify and show signatures' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_failure GPG 'verify-commit exits success on untrusted signature' '
|
test_expect_success GPG 'verify-commit exits success on untrusted signature' '
|
||||||
git verify-commit eighth-signed-alt 2>actual &&
|
git verify-commit eighth-signed-alt 2>actual &&
|
||||||
grep "Good signature from" actual &&
|
grep "Good signature from" actual &&
|
||||||
! grep "BAD signature from" actual &&
|
! grep "BAD signature from" actual &&
|
||||||
|
Loading…
Reference in New Issue
Block a user