Skip to content

Commit 42d4e1d

Browse files
bk2204gitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e02a714 commit 42d4e1d

File tree

5 files changed

+62
-12
lines changed

5 files changed

+62
-12
lines changed

builtin/commit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1659,7 +1659,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
16591659
}
16601660

16611661
if (amend) {
1662-
const char *exclude_gpgsig[2] = { "gpgsig", NULL };
1662+
const char *exclude_gpgsig[3] = { "gpgsig", "gpgsig-sha256", NULL };
16631663
extra = read_commit_extra_headers(current_head, exclude_gpgsig);
16641664
} else {
16651665
struct commit_extra_header **tail = &extra;

commit.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -961,14 +961,22 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
961961
return ret;
962962
}
963963

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+
};
966972

967973
static int do_sign_commit(struct strbuf *buf, const char *keyid)
968974
{
969975
struct strbuf sig = STRBUF_INIT;
970976
int inspos, copypos;
971977
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);
972980

973981
/* find the end of the header */
974982
eoh = strstr(buf->buf, "\n\n");
@@ -1010,6 +1018,8 @@ int parse_signed_commit(const struct commit *commit,
10101018
const char *buffer = get_commit_buffer(commit, &size);
10111019
int in_signature, saw_signature = -1;
10121020
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);
10131023

10141024
line = buffer;
10151025
tail = buffer + size;
@@ -1056,11 +1066,17 @@ int remove_signature(struct strbuf *buf)
10561066

10571067
if (in_signature && line[0] == ' ')
10581068
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+
}
10641080
} else {
10651081
if (*line == '\n')
10661082
/* dump the whole remainder of the buffer */

sequencer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ static int try_to_commit(struct repository *r,
13211321
return -1;
13221322

13231323
if (flags & AMEND_MSG) {
1324-
const char *exclude_gpgsig[] = { "gpgsig", NULL };
1324+
const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL };
13251325
const char *out_enc = get_commit_output_encoding();
13261326
const char *message = logmsg_reencode(current_head, NULL,
13271327
out_enc);

t/t1450-fsck.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,30 @@ test_expect_success 'other worktree HEAD link pointing at a funny place' '
133133
test_i18ngrep "worktrees/other/HEAD points to something strange" out
134134
'
135135

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+
136160
test_expect_success 'email without @ is okay' '
137161
git cat-file commit HEAD >basis &&
138162
sed "s/@/AT/" basis >okay &&

t/t7510-signed-commit.sh

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ GNUPGHOME_NOT_USED=$GNUPGHOME
66
. "$TEST_DIRECTORY/lib-gpg.sh"
77

88
test_expect_success GPG 'create signed commits' '
9+
test_oid_cache <<-\EOF &&
10+
header sha1:gpgsig
11+
header sha256:gpgsig-sha256
12+
EOF
13+
914
test_when_finished "test_unconfig commit.gpgsign" &&
1015
1116
echo 1 >file && git add file &&
@@ -155,14 +160,19 @@ test_expect_success GPG 'verify signatures with --raw' '
155160
)
156161
'
157162

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+
158168
test_expect_success GPG 'show signed commit with signature' '
159169
git show -s initial >commit &&
160170
git show -s --show-signature initial >show &&
161171
git verify-commit -v initial >verify.1 2>verify.2 &&
162172
git cat-file commit initial >cat &&
163173
grep -v -e "gpg: " -e "Warning: " show >show.commit &&
164174
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 &&
166176
test_cmp show.commit commit &&
167177
test_cmp show.gpg verify.2 &&
168178
test_cmp cat.commit verify.1
@@ -299,10 +309,10 @@ test_expect_success GPG 'check config gpg.format values' '
299309
test_expect_success GPG 'detect fudged commit with double signature' '
300310
sed -e "/gpgsig/,/END PGP/d" forged1 >double-base &&
301311
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 &&
303313
gpg -o double-sig2.sig -u 29472784 --detach-sign double-base &&
304314
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/^/ /" \
306316
double-combined.asc > double-gpgsig &&
307317
sed -e "/committer/r double-gpgsig" double-base >double-commit &&
308318
git hash-object -w -t commit double-commit >double-commit.commit &&

0 commit comments

Comments
 (0)