@matheusbsbs / matheus-bagliano / commits / 42d4e1d112
Fork 0

commit: use expected signature header for SHA-256

The transition plan anticipates that we will allow signatures using multiple algorithms in a single commit. In order to do so, we need to use a different header per algorithm so that it will be obvious over which data to compute the signature. The transition plan specifies that we should use "gpgsig-sha256", so wire up the commit code such that it can write and parse the current algorithm, and it can remove the headers for any algorithm when creating a new commit. Add tests to ensure that we write using the right header and that git fsck doesn't reject these commits. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

brian m. carlson committed Feb 22, 2020 at 20:17 UTC 42d4e1d1128fa1cb56032ac58f65ea3dd1296a9a
5 files changed +62 -12
builtin/commit.c
+1 -1
@@ -1659,7 +1659,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
1659 }
1660
1661 if (amend) {
1662 - const char *exclude_gpgsig[2] = { "gpgsig", NULL };
1662 + const char *exclude_gpgsig[3] = { "gpgsig", "gpgsig-sha256", NULL };
1663 extra = read_commit_extra_headers(current_head, exclude_gpgsig);
1664 } else {
1665 struct commit_extra_header **tail = &extra;
commit.c
+23 -7
@@ -961,14 +961,22 @@ cleanup_return:
961 return ret;
962 }
963
964 -static const char gpg_sig_header[] = "gpgsig";
965 -static const int gpg_sig_header_len = sizeof(gpg_sig_header) - 1;
964 +/*
965 + * Indexed by hash algorithm identifier.
966 + */
967 +static const char *gpg_sig_headers[] = {
968 + NULL,
969 + "gpgsig",
970 + "gpgsig-sha256",
971 +};
972
973 static int do_sign_commit(struct strbuf *buf, const char *keyid)
974 {
975 struct strbuf sig = STRBUF_INIT;
976 int inspos, copypos;
977 const char *eoh;
978 + const char *gpg_sig_header = gpg_sig_headers[hash_algo_by_ptr(the_hash_algo)];
979 + int gpg_sig_header_len = strlen(gpg_sig_header);
980
981 /* find the end of the header */
982 eoh = strstr(buf->buf, "\n\n");
@@ -1010,6 +1018,8 @@ int parse_signed_commit(const struct commit *commit,
1018 const char *buffer = get_commit_buffer(commit, &size);
1019 int in_signature, saw_signature = -1;
1020 const char *line, *tail;
1021 + const char *gpg_sig_header = gpg_sig_headers[hash_algo_by_ptr(the_hash_algo)];
1022 + int gpg_sig_header_len = strlen(gpg_sig_header);
1023
1024 line = buffer;
1025 tail = buffer + size;
@@ -1056,11 +1066,17 @@ int remove_signature(struct strbuf *buf)
1066
1067 if (in_signature && line[0] == ' ')
1068 sig_end = next;
1059 - else if (starts_with(line, gpg_sig_header) &&
1060 - line[gpg_sig_header_len] == ' ') {
1061 - sig_start = line;
1062 - sig_end = next;
1063 - in_signature = 1;
1069 + else if (starts_with(line, "gpgsig")) {
1070 + int i;
1071 + for (i = 1; i < GIT_HASH_NALGOS; i++) {
1072 + const char *p;
1073 + if (skip_prefix(line, gpg_sig_headers[i], &p) &&
1074 + *p == ' ') {
1075 + sig_start = line;
1076 + sig_end = next;
1077 + in_signature = 1;
1078 + }
1079 + }
1080 } else {
1081 if (*line == '\n')
1082 /* dump the whole remainder of the buffer */
sequencer.c
+1 -1
@@ -1321,7 +1321,7 @@ static int try_to_commit(struct repository *r,
1321 return -1;
1322
1323 if (flags & AMEND_MSG) {
1324 - const char *exclude_gpgsig[] = { "gpgsig", NULL };
1324 + const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL };
1325 const char *out_enc = get_commit_output_encoding();
1326 const char *message = logmsg_reencode(current_head, NULL,
1327 out_enc);
t/t1450-fsck.sh
+24
@@ -133,6 +133,30 @@ test_expect_success 'other worktree HEAD link pointing at a funny place' '
133 test_i18ngrep "worktrees/other/HEAD points to something strange" out
134 '
135
136 +test_expect_success 'commit with multiple signatures is okay' '
137 + git cat-file commit HEAD >basis &&
138 + cat >sigs <<-EOF &&
139 + gpgsig -----BEGIN PGP SIGNATURE-----
140 + VGhpcyBpcyBub3QgcmVhbGx5IGEgc2lnbmF0dXJlLg==
141 + -----END PGP SIGNATURE-----
142 + gpgsig-sha256 -----BEGIN PGP SIGNATURE-----
143 + VGhpcyBpcyBub3QgcmVhbGx5IGEgc2lnbmF0dXJlLg==
144 + -----END PGP SIGNATURE-----
145 + EOF
146 + sed -e "/^committer/q" basis >okay &&
147 + cat sigs >>okay &&
148 + echo >>okay &&
149 + sed -e "1,/^$/d" basis >>okay &&
150 + cat okay &&
151 + new=$(git hash-object -t commit -w --stdin <okay) &&
152 + test_when_finished "remove_object $new" &&
153 + git update-ref refs/heads/bogus "$new" &&
154 + test_when_finished "git update-ref -d refs/heads/bogus" &&
155 + git fsck 2>out &&
156 + cat out &&
157 + ! grep "commit $new" out
158 +'
159 +
160 test_expect_success 'email without @ is okay' '
161 git cat-file commit HEAD >basis &&
162 sed "s/@/AT/" basis >okay &&
t/t7510-signed-commit.sh
+13 -3
@@ -6,6 +6,11 @@ GNUPGHOME_NOT_USED=$GNUPGHOME
6 . "$TEST_DIRECTORY/lib-gpg.sh"
7
8 test_expect_success GPG 'create signed commits' '
9 + test_oid_cache <<-\EOF &&
10 + header sha1:gpgsig
11 + header sha256:gpgsig-sha256
12 + EOF
13 +
14 test_when_finished "test_unconfig commit.gpgsign" &&
15
16 echo 1 >file && git add file &&
@@ -155,6 +160,11 @@ test_expect_success GPG 'verify signatures with --raw' '
160 )
161 '
162
163 +test_expect_success GPG 'proper header is used for hash algorithm' '
164 + git cat-file commit fourth-signed >output &&
165 + grep "^$(test_oid header) -----BEGIN PGP SIGNATURE-----" output
166 +'
167 +
168 test_expect_success GPG 'show signed commit with signature' '
169 git show -s initial >commit &&
170 git show -s --show-signature initial >show &&
@@ -162,7 +172,7 @@ test_expect_success GPG 'show signed commit with signature' '
172 git cat-file commit initial >cat &&
173 grep -v -e "gpg: " -e "Warning: " show >show.commit &&
174 grep -e "gpg: " -e "Warning: " show >show.gpg &&
165 - grep -v "^ " cat | grep -v "^gpgsig " >cat.commit &&
175 + grep -v "^ " cat | grep -v "^$(test_oid header) " >cat.commit &&
176 test_cmp show.commit commit &&
177 test_cmp show.gpg verify.2 &&
178 test_cmp cat.commit verify.1
@@ -299,10 +309,10 @@ test_expect_success GPG 'check config gpg.format values' '
309 test_expect_success GPG 'detect fudged commit with double signature' '
310 sed -e "/gpgsig/,/END PGP/d" forged1 >double-base &&
311 sed -n -e "/gpgsig/,/END PGP/p" forged1 | \
302 - sed -e "s/^gpgsig//;s/^ //" | gpg --dearmor >double-sig1.sig &&
312 + sed -e "s/^$(test_oid header)//;s/^ //" | gpg --dearmor >double-sig1.sig &&
313 gpg -o double-sig2.sig -u 29472784 --detach-sign double-base &&
314 cat double-sig1.sig double-sig2.sig | gpg --enarmor >double-combined.asc &&
305 - sed -e "s/^\(-.*\)ARMORED FILE/\1SIGNATURE/;1s/^/gpgsig /;2,\$s/^/ /" \
315 + sed -e "s/^\(-.*\)ARMORED FILE/\1SIGNATURE/;1s/^/$(test_oid header) /;2,\$s/^/ /" \
316 double-combined.asc > double-gpgsig &&
317 sed -e "/committer/r double-gpgsig" double-base >double-commit &&
318 git hash-object -w -t commit double-commit >double-commit.commit &&