#!/bin/sh global test_description := ''signed commit tests'' source ./test-lib.sh global GNUPGHOME_NOT_USED := $GNUPGHOME source "$TEST_DIRECTORY/lib-gpg.sh" test_expect_success GPG 'create signed commits' ' test_when_finished "test_unconfig commit.gpgsign" && echo 1 >file && git add file && test_tick && git commit -S -m initial && git tag initial && git branch side && echo 2 >file && test_tick && git commit -a -S -m second && git tag second && git checkout side && echo 3 >elif && git add elif && test_tick && git commit -m "third on side" && git checkout master && test_tick && git merge -S side && git tag merge && echo 4 >file && test_tick && git commit -a -m "fourth unsigned" && git tag fourth-unsigned && test_tick && git commit --amend -S -m "fourth signed" && git tag fourth-signed && git config commit.gpgsign true && echo 5 >file && test_tick && git commit -a -m "fifth signed" && git tag fifth-signed && git config commit.gpgsign false && echo 6 >file && test_tick && git commit -a -m "sixth" && git tag sixth-unsigned && git config commit.gpgsign true && echo 7 >file && test_tick && git commit -a -m "seventh" --no-gpg-sign && git tag seventh-unsigned && test_tick && git rebase -f HEAD^^ && git tag sixth-signed HEAD^ && git tag seventh-signed && echo 8 >file && test_tick && git commit -a -m eighth -SB7227189 && git tag eighth-signed-alt && # commit.gpgsign is still on but this must not be signed git tag ninth-unsigned $(echo 9 | git commit-tree HEAD^{tree}) && # explicit -S of course must sign. git tag tenth-signed $(echo 9 | git commit-tree -S HEAD^{tree}) ' test_expect_success GPG 'verify and show signatures' ' ( for commit in initial second merge fourth-signed \ fifth-signed sixth-signed seventh-signed tenth-signed do git verify-commit $commit && git show --pretty=short --show-signature $commit >actual && grep "Good signature from" actual && ! grep "BAD signature from" actual && echo $commit OK || exit 1 done ) && ( for commit in merge^2 fourth-unsigned sixth-unsigned \ seventh-unsigned ninth-unsigned do test_must_fail git verify-commit $commit && git show --pretty=short --show-signature $commit >actual && ! grep "Good signature from" actual && ! grep "BAD signature from" actual && echo $commit OK || exit 1 done ) && ( for commit in eighth-signed-alt do git show --pretty=short --show-signature $commit >actual && grep "Good signature from" actual && ! grep "BAD signature from" actual && grep "not certified" actual && echo $commit OK || exit 1 done ) ' test_expect_success GPG 'verify-commit exits success on untrusted signature' ' git verify-commit eighth-signed-alt 2>actual && grep "Good signature from" actual && ! grep "BAD signature from" actual && grep "not certified" actual ' test_expect_success GPG 'verify signatures with --raw' ' ( for commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed do git verify-commit --raw $commit 2>actual && grep "GOODSIG" actual && ! grep "BADSIG" actual && echo $commit OK || exit 1 done ) && ( for commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned do test_must_fail git verify-commit --raw $commit 2>actual && ! grep "GOODSIG" actual && ! grep "BADSIG" actual && echo $commit OK || exit 1 done ) && ( for commit in eighth-signed-alt do git verify-commit --raw $commit 2>actual && grep "GOODSIG" actual && ! grep "BADSIG" actual && grep "TRUST_UNDEFINED" actual && echo $commit OK || exit 1 done ) ' test_expect_success GPG 'show signed commit with signature' ' git show -s initial >commit && git show -s --show-signature initial >show && git verify-commit -v initial >verify.1 2>verify.2 && git cat-file commit initial >cat && grep -v -e "gpg: " -e "Warning: " show >show.commit && grep -e "gpg: " -e "Warning: " show >show.gpg && grep -v "^ " cat | grep -v "^gpgsig " >cat.commit && test_cmp show.commit commit && test_cmp show.gpg verify.2 && test_cmp cat.commit verify.1 ' test_expect_success GPG 'detect fudged signature' ' git cat-file commit seventh-signed >raw && sed -e "s/seventh/7th forged/" raw >forged1 && git hash-object -w -t commit forged1 >forged1.commit && ! git verify-commit $(cat forged1.commit) && git show --pretty=short --show-signature $(cat forged1.commit) >actual1 && grep "BAD signature from" actual1 && ! grep "Good signature from" actual1 ' test_expect_success GPG 'detect fudged signature with NUL' ' git cat-file commit seventh-signed >raw && cat raw >forged2 && echo Qwik | tr "Q" "\000" >>forged2 && git hash-object -w -t commit forged2 >forged2.commit && ! git verify-commit $(cat forged2.commit) && git show --pretty=short --show-signature $(cat forged2.commit) >actual2 && grep "BAD signature from" actual2 && ! grep "Good signature from" actual2 ' test_expect_success GPG 'amending already signed commit' ' git checkout fourth-signed^0 && git commit --amend -S --no-edit && git verify-commit HEAD && git show -s --show-signature HEAD >actual && grep "Good signature from" actual && ! grep "BAD signature from" actual ' test_expect_success GPG 'show good signature with custom format' ' cat >expect <<-\EOF && G 13B6F51ECDDE430D C O Mitter EOF git log -1 --format="%G?%n%GK%n%GS" sixth-signed >actual && test_cmp expect actual ' test_expect_success GPG 'show bad signature with custom format' ' cat >expect <<-\EOF && B 13B6F51ECDDE430D C O Mitter EOF git log -1 --format="%G?%n%GK%n%GS" $(cat forged1.commit) >actual && test_cmp expect actual ' test_expect_success GPG 'show untrusted signature with custom format' ' cat >expect <<-\EOF && U 61092E85B7227189 Eris Discordia EOF git log -1 --format="%G?%n%GK%n%GS" eighth-signed-alt >actual && test_cmp expect actual ' test_expect_success GPG 'show unknown signature with custom format' ' cat >expect <<-\EOF && E 61092E85B7227189 EOF GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GK%n%GS" eighth-signed-alt >actual && test_cmp expect actual ' test_expect_success GPG 'show lack of signature with custom format' ' cat >expect <<-\EOF && N EOF git log -1 --format="%G?%n%GK%n%GS" seventh-unsigned >actual && test_cmp expect actual ' test_expect_success GPG 'log.showsignature behaves like --show-signature' ' test_config log.showsignature true && git show initial >actual && grep "gpg: Signature made" actual && grep "gpg: Good signature" actual ' test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"signed commit tests">)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:GNUPGHOME_NOT_USED) op: Equal rhs: {($ VSub_Name "$GNUPGHOME")} spids: [13] ) ] spids: [13] ) (C {(.)} {(DQ ($ VSub_Name "$TEST_DIRECTORY") (/lib-gpg.sh))}) (C {(test_expect_success)} {(GPG)} {(SQ <"create signed commits">)} { (SQ <"\n"> <"\ttest_when_finished \"test_unconfig commit.gpgsign\" &&\n"> <"\n"> <"\techo 1 >file && git add file &&\n"> <"\ttest_tick && git commit -S -m initial &&\n"> <"\tgit tag initial &&\n"> <"\tgit branch side &&\n"> <"\n"> <"\techo 2 >file && test_tick && git commit -a -S -m second &&\n"> <"\tgit tag second &&\n"> <"\n"> <"\tgit checkout side &&\n"> <"\techo 3 >elif && git add elif &&\n"> <"\ttest_tick && git commit -m \"third on side\" &&\n"> <"\n"> <"\tgit checkout master &&\n"> <"\ttest_tick && git merge -S side &&\n"> <"\tgit tag merge &&\n"> <"\n"> <"\techo 4 >file && test_tick && git commit -a -m \"fourth unsigned\" &&\n"> <"\tgit tag fourth-unsigned &&\n"> <"\n"> <"\ttest_tick && git commit --amend -S -m \"fourth signed\" &&\n"> <"\tgit tag fourth-signed &&\n"> <"\n"> <"\tgit config commit.gpgsign true &&\n"> <"\techo 5 >file && test_tick && git commit -a -m \"fifth signed\" &&\n"> <"\tgit tag fifth-signed &&\n"> <"\n"> <"\tgit config commit.gpgsign false &&\n"> <"\techo 6 >file && test_tick && git commit -a -m \"sixth\" &&\n"> <"\tgit tag sixth-unsigned &&\n"> <"\n"> <"\tgit config commit.gpgsign true &&\n"> <"\techo 7 >file && test_tick && git commit -a -m \"seventh\" --no-gpg-sign &&\n"> <"\tgit tag seventh-unsigned &&\n"> <"\n"> <"\ttest_tick && git rebase -f HEAD^^ && git tag sixth-signed HEAD^ &&\n"> <"\tgit tag seventh-signed &&\n"> <"\n"> <"\techo 8 >file && test_tick && git commit -a -m eighth -SB7227189 &&\n"> <"\tgit tag eighth-signed-alt &&\n"> <"\n"> <"\t# commit.gpgsign is still on but this must not be signed\n"> <"\tgit tag ninth-unsigned $(echo 9 | git commit-tree HEAD^{tree}) &&\n"> <"\t# explicit -S of course must sign.\n"> <"\tgit tag tenth-signed $(echo 9 | git commit-tree -S HEAD^{tree})\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"verify and show signatures">)} { (SQ <"\n"> <"\t(\n"> <"\t\tfor commit in initial second merge fourth-signed \\\n"> <"\t\t\tfifth-signed sixth-signed seventh-signed tenth-signed\n"> <"\t\tdo\n"> <"\t\t\tgit verify-commit $commit &&\n"> <"\t\t\tgit show --pretty=short --show-signature $commit >actual &&\n"> <"\t\t\tgrep \"Good signature from\" actual &&\n"> <"\t\t\t! grep \"BAD signature from\" actual &&\n"> <"\t\t\techo $commit OK || exit 1\n"> <"\t\tdone\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tfor commit in merge^2 fourth-unsigned sixth-unsigned \\\n"> <"\t\t\tseventh-unsigned ninth-unsigned\n"> <"\t\tdo\n"> <"\t\t\ttest_must_fail git verify-commit $commit &&\n"> <"\t\t\tgit show --pretty=short --show-signature $commit >actual &&\n"> <"\t\t\t! grep \"Good signature from\" actual &&\n"> <"\t\t\t! grep \"BAD signature from\" actual &&\n"> <"\t\t\techo $commit OK || exit 1\n"> <"\t\tdone\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tfor commit in eighth-signed-alt\n"> <"\t\tdo\n"> <"\t\t\tgit show --pretty=short --show-signature $commit >actual &&\n"> <"\t\t\tgrep \"Good signature from\" actual &&\n"> <"\t\t\t! grep \"BAD signature from\" actual &&\n"> <"\t\t\tgrep \"not certified\" actual &&\n"> <"\t\t\techo $commit OK || exit 1\n"> <"\t\tdone\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"verify-commit exits success on untrusted signature">)} { (SQ <"\n"> <"\tgit verify-commit eighth-signed-alt 2>actual &&\n"> <"\tgrep \"Good signature from\" actual &&\n"> <"\t! grep \"BAD signature from\" actual &&\n"> <"\tgrep \"not certified\" actual\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"verify signatures with --raw">)} { (SQ <"\n"> <"\t(\n"> < "\t\tfor commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed\n" > <"\t\tdo\n"> <"\t\t\tgit verify-commit --raw $commit 2>actual &&\n"> <"\t\t\tgrep \"GOODSIG\" actual &&\n"> <"\t\t\t! grep \"BADSIG\" actual &&\n"> <"\t\t\techo $commit OK || exit 1\n"> <"\t\tdone\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tfor commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned\n"> <"\t\tdo\n"> <"\t\t\ttest_must_fail git verify-commit --raw $commit 2>actual &&\n"> <"\t\t\t! grep \"GOODSIG\" actual &&\n"> <"\t\t\t! grep \"BADSIG\" actual &&\n"> <"\t\t\techo $commit OK || exit 1\n"> <"\t\tdone\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tfor commit in eighth-signed-alt\n"> <"\t\tdo\n"> <"\t\t\tgit verify-commit --raw $commit 2>actual &&\n"> <"\t\t\tgrep \"GOODSIG\" actual &&\n"> <"\t\t\t! grep \"BADSIG\" actual &&\n"> <"\t\t\tgrep \"TRUST_UNDEFINED\" actual &&\n"> <"\t\t\techo $commit OK || exit 1\n"> <"\t\tdone\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"show signed commit with signature">)} { (SQ <"\n"> <"\tgit show -s initial >commit &&\n"> <"\tgit show -s --show-signature initial >show &&\n"> <"\tgit verify-commit -v initial >verify.1 2>verify.2 &&\n"> <"\tgit cat-file commit initial >cat &&\n"> <"\tgrep -v -e \"gpg: \" -e \"Warning: \" show >show.commit &&\n"> <"\tgrep -e \"gpg: \" -e \"Warning: \" show >show.gpg &&\n"> <"\tgrep -v \"^ \" cat | grep -v \"^gpgsig \" >cat.commit &&\n"> <"\ttest_cmp show.commit commit &&\n"> <"\ttest_cmp show.gpg verify.2 &&\n"> <"\ttest_cmp cat.commit verify.1\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"detect fudged signature">)} { (SQ <"\n"> <"\tgit cat-file commit seventh-signed >raw &&\n"> <"\n"> <"\tsed -e \"s/seventh/7th forged/\" raw >forged1 &&\n"> <"\tgit hash-object -w -t commit forged1 >forged1.commit &&\n"> <"\t! git verify-commit $(cat forged1.commit) &&\n"> <"\tgit show --pretty=short --show-signature $(cat forged1.commit) >actual1 &&\n"> <"\tgrep \"BAD signature from\" actual1 &&\n"> <"\t! grep \"Good signature from\" actual1\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"detect fudged signature with NUL">)} { (SQ <"\n"> <"\tgit cat-file commit seventh-signed >raw &&\n"> <"\tcat raw >forged2 &&\n"> <"\techo Qwik | tr \"Q\" \"\\000\" >>forged2 &&\n"> <"\tgit hash-object -w -t commit forged2 >forged2.commit &&\n"> <"\t! git verify-commit $(cat forged2.commit) &&\n"> <"\tgit show --pretty=short --show-signature $(cat forged2.commit) >actual2 &&\n"> <"\tgrep \"BAD signature from\" actual2 &&\n"> <"\t! grep \"Good signature from\" actual2\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"amending already signed commit">)} { (SQ <"\n"> <"\tgit checkout fourth-signed^0 &&\n"> <"\tgit commit --amend -S --no-edit &&\n"> <"\tgit verify-commit HEAD &&\n"> <"\tgit show -s --show-signature HEAD >actual &&\n"> <"\tgrep \"Good signature from\" actual &&\n"> <"\t! grep \"BAD signature from\" actual\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"show good signature with custom format">)} { (SQ <"\n"> <"\tcat >expect <<-\\EOF &&\n"> <"\tG\n"> <"\t13B6F51ECDDE430D\n"> <"\tC O Mitter \n"> <"\tEOF\n"> <"\tgit log -1 --format=\"%G?%n%GK%n%GS\" sixth-signed >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"show bad signature with custom format">)} { (SQ <"\n"> <"\tcat >expect <<-\\EOF &&\n"> <"\tB\n"> <"\t13B6F51ECDDE430D\n"> <"\tC O Mitter \n"> <"\tEOF\n"> <"\tgit log -1 --format=\"%G?%n%GK%n%GS\" $(cat forged1.commit) >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"show untrusted signature with custom format">)} { (SQ <"\n"> <"\tcat >expect <<-\\EOF &&\n"> <"\tU\n"> <"\t61092E85B7227189\n"> <"\tEris Discordia \n"> <"\tEOF\n"> <"\tgit log -1 --format=\"%G?%n%GK%n%GS\" eighth-signed-alt >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"show unknown signature with custom format">)} { (SQ <"\n"> <"\tcat >expect <<-\\EOF &&\n"> <"\tE\n"> <"\t61092E85B7227189\n"> <"\n"> <"\tEOF\n"> < "\tGNUPGHOME=\"$GNUPGHOME_NOT_USED\" git log -1 --format=\"%G?%n%GK%n%GS\" eighth-signed-alt >actual &&\n" > <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"show lack of signature with custom format">)} { (SQ <"\n"> <"\tcat >expect <<-\\EOF &&\n"> <"\tN\n"> <"\n"> <"\n"> <"\tEOF\n"> <"\tgit log -1 --format=\"%G?%n%GK%n%GS\" seventh-unsigned >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(GPG)} {(SQ <"log.showsignature behaves like --show-signature">)} { (SQ <"\n"> <"\ttest_config log.showsignature true &&\n"> <"\tgit show initial >actual &&\n"> <"\tgrep \"gpg: Signature made\" actual &&\n"> <"\tgrep \"gpg: Good signature\" actual\n"> ) } ) (C {(test_done)}) ] )