From c8525c302bfd8c5bc6a7e2f7aec0be2951eefd90 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Wed, 10 Nov 2010 12:17:26 +0100 Subject: [PATCH 1/5] t/t7004-tag: test handling of rfc1991 signatures Currently, git expects "-----BEGIN PGP SIGNATURE-----" at the beginning of a signature. But gpg uses "MESSAGE" instead of "SIGNATURE" when used with the "rfc1991" option. This leads to git's failing to verify it's own signed tags, among other problems. Add tests for all code paths (tag -v, tag -l -n largenumber, tag -f without -m) where signature detection matters. Reported-by: Stephan Hugel Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- t/t7004-tag.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index ac943f5eee..c7d49e1049 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1030,6 +1030,72 @@ test_expect_success GPG \ test_cmp expect actual ' +# usage with rfc1991 signatures +echo "rfc1991" > gpghome/gpg.conf +get_tag_header rfc1991-signed-tag $commit commit $time >expect +echo "RFC1991 signed tag" >>expect +echo '-----BEGIN PGP MESSAGE-----' >>expect +test_expect_success GPG \ + 'creating a signed tag with rfc1991' ' + git tag -s -m "RFC1991 signed tag" rfc1991-signed-tag $commit && + get_tag_msg rfc1991-signed-tag >actual && + test_cmp expect actual +' + +cat >fakeeditor <<'EOF' +#!/bin/sh +cp "$1" actual +EOF +chmod +x fakeeditor + +test_expect_failure GPG \ + 'reediting a signed tag body omits signature' ' + echo "RFC1991 signed tag" >expect && + GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit && + test_cmp expect actual +' + +test_expect_failure GPG \ + 'verifying rfc1991 signature' ' + git tag -v rfc1991-signed-tag +' + +test_expect_failure GPG \ + 'list tag with rfc1991 signature' ' + echo "rfc1991-signed-tag RFC1991 signed tag" >expect && + git tag -l -n1 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n2 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n999 rfc1991-signed-tag >actual && + test_cmp expect actual +' + +rm -f gpghome/gpg.conf + +test_expect_failure GPG \ + 'verifying rfc1991 signature without --rfc1991' ' + git tag -v rfc1991-signed-tag +' + +test_expect_failure GPG \ + 'list tag with rfc1991 signature without --rfc1991' ' + echo "rfc1991-signed-tag RFC1991 signed tag" >expect && + git tag -l -n1 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n2 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n999 rfc1991-signed-tag >actual && + test_cmp expect actual +' + +test_expect_failure GPG \ + 'reediting a signed tag body omits signature' ' + echo "RFC1991 signed tag" >expect && + GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit && + test_cmp expect actual +' + # try to sign with bad user.signingkey git config user.signingkey BobTheMouse test_expect_success GPG \ From ac58c4c795455addd0d8f007e969d56e43f1165b Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Wed, 10 Nov 2010 12:17:27 +0100 Subject: [PATCH 2/5] verify-tag: factor out signature detection into tag.h/c for later reuse and modification. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- builtin/verify-tag.c | 10 ++-------- tag.c | 13 +++++++++++++ tag.h | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index 9f482c29f5..86cac6d715 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -17,13 +17,11 @@ static const char * const verify_tag_usage[] = { NULL }; -#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----" - static int run_gpg_verify(const char *buf, unsigned long size, int verbose) { struct child_process gpg; const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL}; - char path[PATH_MAX], *eol; + char path[PATH_MAX]; size_t len; int fd, ret; @@ -37,11 +35,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose) close(fd); /* find the length without signature */ - len = 0; - while (len < size && prefixcmp(buf + len, PGP_SIGNATURE)) { - eol = memchr(buf + len, '\n', size - len); - len += eol ? eol - (buf + len) + 1 : size - len; - } + len = parse_signature(buf, size); if (verbose) write_in_full(1, buf, len); diff --git a/tag.c b/tag.c index 28641cf85a..d4f3080e3f 100644 --- a/tag.c +++ b/tag.c @@ -4,6 +4,8 @@ #include "tree.h" #include "blob.h" +#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----" + const char *tag_type = "tag"; struct object *deref_tag(struct object *o, const char *warn, int warnlen) @@ -133,3 +135,14 @@ int parse_tag(struct tag *item) free(data); return ret; } + +size_t parse_signature(const char *buf, unsigned long size) +{ + char *eol; + size_t len = 0; + while (len < size && prefixcmp(buf + len, PGP_SIGNATURE)) { + eol = memchr(buf + len, '\n', size - len); + len += eol ? eol - (buf + len) + 1 : size - len; + } + return len; +} diff --git a/tag.h b/tag.h index 47662724a6..8522370039 100644 --- a/tag.h +++ b/tag.h @@ -16,5 +16,6 @@ extern struct tag *lookup_tag(const unsigned char *sha1); extern int parse_tag_buffer(struct tag *item, void *data, unsigned long size); extern int parse_tag(struct tag *item); extern struct object *deref_tag(struct object *, const char *, int); +extern size_t parse_signature(const char *buf, unsigned long size); #endif /* TAG_H */ From e10dfb62ee21a3970ccfe44f30f97fcd6457bb78 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Wed, 10 Nov 2010 12:17:28 +0100 Subject: [PATCH 3/5] tag: factor out sig detection for body edits Use the factored out code for sig detection when editing existing tag bodies (tag -a -f without -m). Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- builtin/tag.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/builtin/tag.c b/builtin/tag.c index d311491e49..66feeb0c64 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -29,8 +29,6 @@ struct tag_filter { struct commit_list *with_commit; }; -#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----" - static int show_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data) { @@ -242,8 +240,7 @@ static void write_tag_body(int fd, const unsigned char *sha1) { unsigned long size; enum object_type type; - char *buf, *sp, *eob; - size_t len; + char *buf, *sp; buf = read_sha1_file(sha1, &type, &size); if (!buf) @@ -256,12 +253,7 @@ static void write_tag_body(int fd, const unsigned char *sha1) return; } sp += 2; /* skip the 2 LFs */ - eob = strstr(sp, "\n" PGP_SIGNATURE "\n"); - if (eob) - len = eob - sp; - else - len = buf + size - sp; - write_or_die(fd, sp, len); + write_or_die(fd, sp, parse_signature(sp, buf + size - sp)); free(buf); } From 81536b2dfae5a2839b6f20b22cc814a3690e4704 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Wed, 10 Nov 2010 12:17:29 +0100 Subject: [PATCH 4/5] tag: factor out sig detection for tag display Use the factored out code for sig detection when displaying tags. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- builtin/tag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin/tag.c b/builtin/tag.c index 66feeb0c64..617a58f058 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -68,9 +68,9 @@ static int show_reference(const char *refname, const unsigned char *sha1, return 0; } /* only take up to "lines" lines, and strip the signature */ + size = parse_signature(buf, size); for (i = 0, sp += 2; - i < filter->lines && sp < buf + size && - prefixcmp(sp, PGP_SIGNATURE "\n"); + i < filter->lines && sp < buf + size; i++) { if (i) printf("\n "); From 3d5854e765dedfaf2a942e8fa1e950a40f9dcee3 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Wed, 10 Nov 2010 12:17:30 +0100 Subject: [PATCH 5/5] tag: recognize rfc1991 signatures We have always been creating rfc1991 signatures for users with "rfc1991" in their gpg config but failed to recognize them (tag -l -n largenumber) and verify them (tag -v, verify-tag). Make good use of the refactored signature detection and let us recognize and verify those signatures also. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- t/t7004-tag.sh | 12 ++++++------ tag.c | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index c7d49e1049..6841c23c0a 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1048,19 +1048,19 @@ cp "$1" actual EOF chmod +x fakeeditor -test_expect_failure GPG \ +test_expect_success GPG \ 'reediting a signed tag body omits signature' ' echo "RFC1991 signed tag" >expect && GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit && test_cmp expect actual ' -test_expect_failure GPG \ +test_expect_success GPG \ 'verifying rfc1991 signature' ' git tag -v rfc1991-signed-tag ' -test_expect_failure GPG \ +test_expect_success GPG \ 'list tag with rfc1991 signature' ' echo "rfc1991-signed-tag RFC1991 signed tag" >expect && git tag -l -n1 rfc1991-signed-tag >actual && @@ -1073,12 +1073,12 @@ test_expect_failure GPG \ rm -f gpghome/gpg.conf -test_expect_failure GPG \ +test_expect_success GPG \ 'verifying rfc1991 signature without --rfc1991' ' git tag -v rfc1991-signed-tag ' -test_expect_failure GPG \ +test_expect_success GPG \ 'list tag with rfc1991 signature without --rfc1991' ' echo "rfc1991-signed-tag RFC1991 signed tag" >expect && git tag -l -n1 rfc1991-signed-tag >actual && @@ -1089,7 +1089,7 @@ test_expect_failure GPG \ test_cmp expect actual ' -test_expect_failure GPG \ +test_expect_success GPG \ 'reediting a signed tag body omits signature' ' echo "RFC1991 signed tag" >expect && GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit && diff --git a/tag.c b/tag.c index d4f3080e3f..f789744cca 100644 --- a/tag.c +++ b/tag.c @@ -5,6 +5,7 @@ #include "blob.h" #define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----" +#define PGP_MESSAGE "-----BEGIN PGP MESSAGE-----" const char *tag_type = "tag"; @@ -140,7 +141,8 @@ size_t parse_signature(const char *buf, unsigned long size) { char *eol; size_t len = 0; - while (len < size && prefixcmp(buf + len, PGP_SIGNATURE)) { + while (len < size && prefixcmp(buf + len, PGP_SIGNATURE) && + prefixcmp(buf + len, PGP_MESSAGE)) { eol = memchr(buf + len, '\n', size - len); len += eol ? eol - (buf + len) + 1 : size - len; }