mirror of
https://github.com/git/git
synced 2024-08-27 11:39:22 +00:00
![SZEDER Gábor](/assets/img/avatar_default.png)
A couple of test scripts create forged GPG signed commits or tags to check that such forgery can't fool various git commands' signature verification. All but one of those test scripts are prone to occasional failures because the forgery creates a bogus GPG signature, and git commands error out with an unexpected error message, e.g. "Commit deadbeef does not have a GPG signature" instead of "... has a bad GPG signature". 't5573-pull-verify-signatures.sh', 't7510-signed-commit.sh' and 't7612-merge-verify-signatures.sh' create forged signed commits like this: git commit -S -m "bad on side" && git cat-file commit side-bad >raw && sed -e "s/bad/forged bad/" raw >forged && git hash-object -w -t commit forged >forged.commit On rare occasions the given pattern occurs not only in the commit message but in the GPG signature as well, and after it's replaced in the signature the resulting signature becomes invalid, GPG will report CRC error and that it couldn't find any signature, which will then ultimately cause the test failure. Since in all three cases the pattern to be replaced during the forgery is the first word of the commit message's subject line, and since the GPG signature in the commit object is indented by a space, let's just anchor those patterns to the beginning of the line to prevent this issue. The test script 't7030-verify-tag.sh' creates a forged signed tag object in a similar way by replacing the pattern "seventh", but the GPG signature in tag objects is not indented by a space, so the above solution is not applicable in this case. However, in the tag object in question the pattern "seventh" occurs not only in the tag message but in the 'tag' header as well. To create a forged tag object it's sufficient to replace only one of the two occurences, so modify the sed script to limit the pattern to the 'tag' header (i.e. a line beginning with "tag ", which, because of the space character, can never occur in the base64-encoded GPG signature). Note that the forgery in 't7004-tag.sh' is not affected by this issue: while 't7004' does create a forged signed tag kind of the same way, it replaces "signed-tag" in the tag object, which, because of the '-' character, can never occur in the base64-encoded GPG signarute. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
107 lines
4 KiB
Bash
Executable file
107 lines
4 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
test_description='merge signature verification tests'
|
|
. ./test-lib.sh
|
|
. "$TEST_DIRECTORY/lib-gpg.sh"
|
|
|
|
test_expect_success GPG 'create signed commits' '
|
|
echo 1 >file && git add file &&
|
|
test_tick && git commit -m initial &&
|
|
git tag initial &&
|
|
|
|
git checkout -b side-signed &&
|
|
echo 3 >elif && git add elif &&
|
|
test_tick && git commit -S -m "signed on side" &&
|
|
git checkout initial &&
|
|
|
|
git checkout -b side-unsigned &&
|
|
echo 3 >foo && git add foo &&
|
|
test_tick && git commit -m "unsigned on side" &&
|
|
git checkout initial &&
|
|
|
|
git checkout -b side-bad &&
|
|
echo 3 >bar && git add bar &&
|
|
test_tick && git commit -S -m "bad on side" &&
|
|
git cat-file commit side-bad >raw &&
|
|
sed -e "s/^bad/forged bad/" raw >forged &&
|
|
git hash-object -w -t commit forged >forged.commit &&
|
|
git checkout initial &&
|
|
|
|
git checkout -b side-untrusted &&
|
|
echo 3 >baz && git add baz &&
|
|
test_tick && git commit -SB7227189 -m "untrusted on side" &&
|
|
|
|
git checkout master
|
|
'
|
|
|
|
test_expect_success GPG 'merge unsigned commit with verification' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_must_fail git merge --ff-only --verify-signatures side-unsigned 2>mergeerror &&
|
|
test_i18ngrep "does not have a GPG signature" mergeerror
|
|
'
|
|
|
|
test_expect_success GPG 'merge unsigned commit with merge.verifySignatures=true' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_config merge.verifySignatures true &&
|
|
test_must_fail git merge --ff-only side-unsigned 2>mergeerror &&
|
|
test_i18ngrep "does not have a GPG signature" mergeerror
|
|
'
|
|
|
|
test_expect_success GPG 'merge commit with bad signature with verification' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_must_fail git merge --ff-only --verify-signatures $(cat forged.commit) 2>mergeerror &&
|
|
test_i18ngrep "has a bad GPG signature" mergeerror
|
|
'
|
|
|
|
test_expect_success GPG 'merge commit with bad signature with merge.verifySignatures=true' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_config merge.verifySignatures true &&
|
|
test_must_fail git merge --ff-only $(cat forged.commit) 2>mergeerror &&
|
|
test_i18ngrep "has a bad GPG signature" mergeerror
|
|
'
|
|
|
|
test_expect_success GPG 'merge commit with untrusted signature with verification' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_must_fail git merge --ff-only --verify-signatures side-untrusted 2>mergeerror &&
|
|
test_i18ngrep "has an untrusted GPG signature" mergeerror
|
|
'
|
|
|
|
test_expect_success GPG 'merge commit with untrusted signature with merge.verifySignatures=true' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_config merge.verifySignatures true &&
|
|
test_must_fail git merge --ff-only side-untrusted 2>mergeerror &&
|
|
test_i18ngrep "has an untrusted GPG signature" mergeerror
|
|
'
|
|
|
|
test_expect_success GPG 'merge signed commit with verification' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
git merge --verbose --ff-only --verify-signatures side-signed >mergeoutput &&
|
|
test_i18ngrep "has a good GPG signature" mergeoutput
|
|
'
|
|
|
|
test_expect_success GPG 'merge signed commit with merge.verifySignatures=true' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_config merge.verifySignatures true &&
|
|
git merge --verbose --ff-only side-signed >mergeoutput &&
|
|
test_i18ngrep "has a good GPG signature" mergeoutput
|
|
'
|
|
|
|
test_expect_success GPG 'merge commit with bad signature without verification' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
git merge $(cat forged.commit)
|
|
'
|
|
|
|
test_expect_success GPG 'merge commit with bad signature with merge.verifySignatures=false' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_config merge.verifySignatures false &&
|
|
git merge $(cat forged.commit)
|
|
'
|
|
|
|
test_expect_success GPG 'merge commit with bad signature with merge.verifySignatures=true and --no-verify-signatures' '
|
|
test_when_finished "git reset --hard && git checkout initial" &&
|
|
test_config merge.verifySignatures true &&
|
|
git merge --no-verify-signatures $(cat forged.commit)
|
|
'
|
|
|
|
test_done
|