summaryrefslogtreecommitdiff
path: root/t/t7510-signed-commit.sh
AgeCommit message (Collapse)AuthorFilesLines
2020-01-15gpg-interface: add minTrustLevel as a configuration optionLibravatar Hans Jerry Illikainen1-0/+39
Previously, signature verification for merge and pull operations checked if the key had a trust-level of either TRUST_NEVER or TRUST_UNDEFINED in verify_merge_signature(). If that was the case, the process die()d. The other code paths that did signature verification relied entirely on the return code from check_commit_signature(). And signatures made with a good key, irregardless of its trust level, was considered valid by check_commit_signature(). This difference in behavior might induce users to erroneously assume that the trust level of a key in their keyring is always considered by Git, even for operations where it is not (e.g. during a verify-commit or verify-tag). The way it worked was by gpg-interface.c storing the result from the key/signature status *and* the lowest-two trust levels in the `result` member of the signature_check structure (the last of these status lines that were encountered got written to `result`). These are documented in GPG under the subsection `General status codes` and `Key related`, respectively [1]. The GPG documentation says the following on the TRUST_ status codes [1]: """ These are several similar status codes: - TRUST_UNDEFINED <error_token> - TRUST_NEVER <error_token> - TRUST_MARGINAL [0 [<validation_model>]] - TRUST_FULLY [0 [<validation_model>]] - TRUST_ULTIMATE [0 [<validation_model>]] For good signatures one of these status lines are emitted to indicate the validity of the key used to create the signature. The error token values are currently only emitted by gpgsm. """ My interpretation is that the trust level is conceptionally different from the validity of the key and/or signature. That seems to also have been the assumption of the old code in check_signature() where a result of 'G' (as in GOODSIG) and 'U' (as in TRUST_NEVER or TRUST_UNDEFINED) were both considered a success. The two cases where a result of 'U' had special meaning were in verify_merge_signature() (where this caused git to die()) and in format_commit_one() (where it affected the output of the %G? format specifier). I think it makes sense to refactor the processing of TRUST_ status lines such that users can configure a minimum trust level that is enforced globally, rather than have individual parts of git (e.g. merge) do it themselves (except for a grace period with backward compatibility). I also think it makes sense to not store the trust level in the same struct member as the key/signature status. While the presence of a TRUST_ status code does imply that the signature is good (see the first paragraph in the included snippet above), as far as I can tell, the order of the status lines from GPG isn't well-defined; thus it would seem plausible that the trust level could be overwritten with the key/signature status if they were stored in the same member of the signature_check structure. This patch introduces a new configuration option: gpg.minTrustLevel. It consolidates trust-level verification to gpg-interface.c and adds a new `trust_level` member to the signature_check structure. Backward-compatibility is maintained by introducing a special case in verify_merge_signature() such that if no user-configurable gpg.minTrustLevel is set, then the old behavior of rejecting TRUST_UNDEFINED and TRUST_NEVER is enforced. If, on the other hand, gpg.minTrustLevel is set, then that value overrides the old behavior. Similarly, the %G? format specifier will continue show 'U' for signatures made with a key that has a trust level of TRUST_UNDEFINED or TRUST_NEVER, even though the 'U' character no longer exist in the `result` member of the signature_check structure. A new format specifier, %GT, is also introduced for users that want to show all possible trust levels for a signature. Another approach would have been to simply drop the trust-level requirement in verify_merge_signature(). This would also have made the behavior consistent with other parts of git that perform signature verification. However, requiring a minimum trust level for signing keys does seem to have a real-world use-case. For example, the build system used by the Qubes OS project currently parses the raw output from verify-tag in order to assert a minimum trust level for keys used to sign git tags [2]. [1] https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/doc/DETAILS;h=bd00006e933ac56719b1edd2478ecd79273eae72;hb=refs/heads/master [2] https://github.com/QubesOS/qubes-builder/blob/9674c1991deef45b1a1b1c71fddfab14ba50dccf/scripts/verify-git-tag#L43 Signed-off-by: Hans Jerry Illikainen <hji@dyntopia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-22commit-tree: add missing --gpg-sign flagLibravatar Brandon Richardson1-3/+12
Add --gpg-sign option in commit-tree, which was documented, but not implemented, in 55ca3f99ae. Add tests for the --gpg-sign option. Signed-off-by: Brandon Richardson <brandon1024.br@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-22t7510: invoke git as part of &&-chainLibravatar Martin Ågren1-2/+6
If `git commit-tree HEAD^{tree}` fails on us and produces no output on stdout, we will substitute that empty string and execute `git tag ninth-unsigned`, i.e., we will tag HEAD rather than a newly created object. But we are lucky: we have a signature on HEAD, so we should eventually fail the next test, where we verify that "ninth-unsigned" is indeed unsigned. We have a similar problem a few lines later. If `git commit-tree -S` fails with no output, we will happily tag HEAD as "tenth-signed". Here, we are not so lucky. The tag ends up on the same commit as "eighth-signed-alt", and that's a signed commit, so t7510-signed-commit will pass, despite `git commit-tree -S` failing. Make these `git commit-tree` invocations a direct part of the &&-chain, so that we can rely less on luck and set a better example for future tests modeled after this one. Fix a 9/10 copy/paste error while at it. Signed-off-by: Martin Ågren <martin.agren@gmail.com> Signed-off-by: Brandon Richardson <brandon1024.br@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-05t/t7510-signed-commit.sh: add signing subkey to Eris Discordia keyLibravatar Michał Górny1-3/+3
Add a dedicated signing subkey to the key identified as 'Eris Discordia', and update tests appropriately. GnuPG will now sign commits using the dedicated signing subkey, changing the value of %GK and %GF, and effectively creating a test case for %GF!=%GP. Signed-off-by: Michał Górny <mgorny@gentoo.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-05t/t7510-signed-commit.sh: Add %GP to custom format checksLibravatar Michał Górny1-6/+12
Test %GP in addition to %GF in custom format checks. With current keyring, both have the same value. Signed-off-by: Michał Górny <mgorny@gentoo.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-23gpg-interface.c: support getting key fingerprint via %GF formatLibravatar Michał Górny1-6/+12
Support processing VALIDSIG status that provides additional information for valid signatures. Use this information to propagate signing key fingerprint and expose it via %GF pretty format. This format can be used to build safer key verification systems that verify the key via complete fingerprint rather than short/long identifier provided by %GK. Signed-off-by: Michał Górny <mgorny@gentoo.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-22gpg-interface.c: detect and reject multiple signatures on commitsLibravatar Michał Górny1-0/+26
GnuPG supports creating signatures consisting of multiple signature packets. If such a signature is verified, it outputs all the status messages for each signature separately. However, git currently does not account for such scenario and gets terribly confused over getting multiple *SIG statuses. For example, if a malicious party alters a signed commit and appends a new untrusted signature, git is going to ignore the original bad signature and report untrusted commit instead. However, %GK and %GS format strings may still expand to the data corresponding to the original signature, potentially tricking the scripts into trusting the malicious commit. Given that the use of multiple signatures is quite rare, git does not support creating them without jumping through a few hoops, and finally supporting them properly would require extensive API improvement, it seems reasonable to just reject them at the moment. Signed-off-by: Michał Górny <mgorny@gentoo.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-18t/t7510: check the validation of the new config gpg.formatLibravatar Henning Schild1-0/+7
Test setting gpg.format to both invalid and valid values. Signed-off-by: Henning Schild <henning.schild@siemens.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-06-11tests: make forging GPG signed commits and tags more robustLibravatar SZEDER Gábor1-2/+1
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>
2018-06-11t7510-signed-commit: use 'test_must_fail'Libravatar SZEDER Gábor1-2/+2
The two tests 'detect fudged signature' and 'detect fudged signature with NUL' in 't7510-signed-commit.sh' check that 'git verify-commit' errors out when encountering a forged commit, but they do so by running ! git verify-commit ... Use 'test_must_fail' instead, because that would catch potential unexpected errors like a segfault as well. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-12gpg-interface: use more status lettersLibravatar Michael J Gruber1-1/+12
According to gpg2's doc/DETAILS: For each signature only one of the codes GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG or ERRSIG will be emitted. gpg1 ("classic") behaves the same (although doc/DETAILS differs). Currently, we parse gpg's status output for GOODSIG, BADSIG and trust information and translate that into status codes G, B, U, N for the %G? format specifier. git-verify-* returns success in the GOODSIG case only. This is somewhat in disagreement with gpg, which considers the first 5 of the 6 above as VALIDSIG, but we err on the very safe side. Introduce additional status codes E, X, Y, R for ERRSIG, EXPSIG, EXPKEYSIG, and REVKEYSIG so that a user of %G? gets more information about the absence of a 'G' on first glance. Requested-by: Alex <agrambot@gmail.com> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-24log: add log.showSignature configuration variableLibravatar Mehul Jain1-0/+7
Users may want to always use "--show-signature" while using git-log and related commands. When log.showSignature is set to true, git-log and related commands will behave as if "--show-signature" was given to them. Note that this config variable is meant to affect git-log, git-show, git-whatchanged and git-reflog. Other commands like git-format-patch, git-rev-list are not to be affected by this config variable. Signed-off-by: Mehul Jain <mehul.jain2029@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-05-13Merge branch 'jc/commit-tree-ignore-commit-gpgsign'Libravatar Junio C Hamano1-3/+10
"git commit-tree" plumbing command required the user to always sign its result when the user sets the commit.gpgsign configuration variable, which was an ancient mistake. Rework "git rebase" that relied on this mistake so that it reads commit.gpgsign and pass (or not pass) the -S option to "git commit-tree" to keep the end-user expectation the same, while teaching "git commit-tree" to ignore the configuration variable. This will stop requiring the users to sign commit objects used internally as an implementation detail of "git stash". * jc/commit-tree-ignore-commit-gpgsign: commit-tree: do not pay attention to commit.gpgsign
2016-05-03commit-tree: do not pay attention to commit.gpgsignLibravatar Junio C Hamano1-3/+10
ba3c69a9 (commit: teach --gpg-sign option, 2011-10-05) introduced a "signed commit" by teaching the --[no]-gpg-sign option and the commit.gpgsign configuration variable to various commands that create commits. Teaching these to "git commit" and "git merge", both of which are end-user facing Porcelain commands, was perfectly fine. Allowing the plumbing "git commit-tree" to suddenly change the behaviour to surprise the scripts by paying attention to commit.gpgsign was not. Among the in-tree scripts, filter-branch, quiltimport, rebase and stash are the commands that run "commit-tree". If any of these wants to allow users to always sign every single commit, they should offer their own configuration (e.g. "filterBranch.gpgsign") with an option to disable signing (e.g. "git filter-branch --no-gpgsign"). Ignoring commit.gpgsign option _obviously_ breaks the backward compatibility, but it is easy to follow the standard pattern in scripts to honor whatever configuration variable they choose to follow. E.g. case $(git config --bool commit.gpgsign) in true) sign=-S ;; *) sign= ;; esac && git commit-tree $sign ...whatever other args... Do so to make sure that "git rebase" keeps paying attention to the configuration variable, which unfortunately is a documented mistake. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-22verify-commit: add option to print raw gpg status informationLibravatar brian m. carlson1-0/+31
verify-commit by default displays human-readable output on standard error. However, it can also be useful to get access to the raw gpg status information, which is machine-readable, allowing automated implementation of signing policy. Add a --raw option to make verify-commit produce the gpg status information on standard error instead of the human-readable format. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-22gpg: centralize signature checkLibravatar brian m. carlson1-1/+1
verify-commit and verify-tag both share a central codepath for verifying commits: check_signature. However, verify-tag exited successfully for untrusted signature, while verify-commit exited unsuccessfully. Centralize this signature check and make verify-commit adopt the older verify-tag behavior. This behavior is more logical anyway, as the signature is in fact valid, whether or not there's a path of trust to the author. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-22verify-commit: add test for exit status on untrusted signatureLibravatar brian m. carlson1-0/+7
verify-tag exits successfully if the signature is good but the key is untrusted. verify-commit exits unsuccessfully. This divergence in behavior is unexpected and unwanted. Since verify-tag existed earlier, add a failing test to have verify-commit share verify-tag's behavior. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-26Merge branch 'jk/test-chain-lint'Libravatar Junio C Hamano1-1/+1
People often forget to chain the commands in their test together with &&, leaving a failure from an earlier command in the test go unnoticed. The new GIT_TEST_CHAIN_LINT mechanism allows you to catch such a mistake more easily. * jk/test-chain-lint: (36 commits) t9001: drop save_confirm helper t0020: use test_* helpers instead of hand-rolled messages t: simplify loop exit-code status variables t: fix some trivial cases of ignored exit codes in loops t7701: fix ignored exit code inside loop t3305: fix ignored exit code inside loop t0020: fix ignored exit code inside loops perf-lib: fix ignored exit code inside loop t6039: fix broken && chain t9158, t9161: fix broken &&-chain in git-svn tests t9104: fix test for following larger parents t4104: drop hand-rolled error reporting t0005: fix broken &&-chains t7004: fix embedded single-quotes t0050: appease --chain-lint t9001: use test_when_finished t4117: use modern test_* helpers t6034: use modern test_* helpers t1301: use modern test_* helpers t0020: use modern test_* helpers ...
2015-03-20Merge branch 'mg/verify-commit'Libravatar Junio C Hamano1-2/+2
Workarounds for certain build of GPG that triggered false breakage in a test. * mg/verify-commit: t7510: do not fail when gpg warns about insecure memory
2015-03-20t: fix trivial &&-chain breakageLibravatar Jeff King1-1/+1
These are tests which are missing a link in their &&-chain, but during a setup phase. We may fail to notice failure in commands that build the test environment, but these are typically not expected to fail at all (but it's still good to double-check that our test environment is what we expect). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-10t7510: do not fail when gpg warns about insecure memoryLibravatar Kyle J. McKay1-2/+2
Depending on how gpg was built, it may issue the following message to stderr when run: Warning: using insecure memory! When the test is collecting gpg output it is therefore not enough to just match on a "gpg: " prefix it must also match on a "Warning: " prefix wherever it needs to match lines that have been produced by gpg. Signed-off-by: Kyle J. McKay <mackyle@gmail.com> Acked-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-10Merge branch 'mg/verify-commit'Libravatar Junio C Hamano1-1/+19
Add 'verify-commit' to be used in a way similar to 'verify-tag' is used. Further work on verifying the mergetags might be needed. * mg/verify-commit: t7510: test verify-commit t7510: exit for loop with test result verify-commit: scriptable commit signature verification gpg-interface: provide access to the payload gpg-interface: provide clear helper for struct signature_check
2014-06-25move "%G" format test from t7510 to t6006Libravatar Jeff King1-6/+0
The final test in t7510 checks that "--format" placeholders that look similar to GPG placeholders (but that we don't actually understand) are passed through. That test was placed in t7510, since the other GPG placeholder tests are there. However, it does not have a GPG prerequisite, because it is not actually checking any signed commits. This causes the test to erroneously fail when gpg is not installed on a system, however. Not because we need signed commits, but because we need _any_ commit to run "git log". If we don't have gpg installed, t7510 doesn't create any commits at all. We can fix this by moving the test into t6006. This is arguably a better place anyway, because it is where we test most of the other placeholders (we do not test GPG placeholders there because of the infrastructure needed to make signed commits). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-23t7510: test verify-commitLibravatar Michael J Gruber1-1/+19
This mixes the "git verify-commit" tests in with the "git show --show-signature" tests, to keep the tests more readable. The tests already mix in the "call show" tests with the "verify" tests. So in case of a test beakage, a '-v' run would be needed to reveal the exact point of breakage anyway. Additionally, test the actual output of "git verify-commit" and "git show --show-signature" and compare to "git cat-file". Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-23t7510: exit for loop with test resultLibravatar Michael J Gruber1-2/+2
t7510 uses for loops in a subshell, which need to make sure that the test returns with the appropriate error code from within the loop. Restructure the loops as the usual && chains with a single point of "exit 1" at the end of the loop to make this clearer. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17pretty: avoid reading past end-of-string with "%G"Libravatar Jeff King1-0/+6
If the user asks for --format=%G with nothing else, we correctly realize that "%G" is not a valid placeholder (it should be "%G?", "%GK", etc). But we still tell the strbuf_expand code that we consumed 2 characters, causing it to jump over the trailing NUL and output garbage. This also fixes the case where "%GX" would be consumed (and produce no output). In other cases, we pass unrecognized placeholders through to the final string. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17t7510: check %G* pretty-format outputLibravatar Jeff King1-0/+40
We do not check these along with the other pretty-format placeholders in t6006, because we need signed commits to make them interesting. t7510 has such commits, and can easily exercise them in addition to the regular --show-signature code path. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17t7510: test a commit signed by an unknown keyLibravatar Jeff King1-0/+13
We tested both good and bad signatures, but not ones made correctly but with a key for which we have no trust. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17t7510: use consistent &&-chains in loopLibravatar Michael J Gruber1-6/+6
We check multiple commits in a loop. Because we want to break out of the loop if any single iteration fails, we use a subshell/exit like: ( for i in $stuff do do-something $i || exit 1 done ) However, we are inconsistent in our loop body. Some commands get their own "|| exit 1", and others try to chain to the next command with "&&", like: X && Y || exit 1 Z || exit 1 This is a little hard to read and follow, because X and Y are treated differently for no good reason. But much worse, the second loop follows a similar pattern and gets it wrong. "Y" is expected to fail, so we use "&& exit 1", giving us: X && Y && exit 1 Z || exit 1 That gets the test for X wrong (we do not exit unless both X fails and Y unexpectedly succeeds, but we would want to exit if _either_ is wrong). We can write this clearly and correctly by consistently using "&&", followed by a single "|| exit 1", and negating Y with "!" (as we would in a normal &&-chain). Like: X && ! Y && Z || exit 1 Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17t7510: stop referring to master in later testsLibravatar Jeff King1-3/+3
Our setup creates a sequence of commits, each with its own tag. However, we sometimes refer to "seventh-signed" as "master". This works, since it is at the tip of the created branch, but is brittle if new tests need to add more commits. Let's use its tag name to be unambiguous. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-24test the commit.gpgsign config optionLibravatar Nicolas Vigier1-4/+21
The tests are checking that : - when commit.gpgsign is true, "git commit" creates signed commits - when commit.gpgsign is false, "git commit" creates unsigned commits - when commit.gpgsign is true, "git commit --no-gpg-sign" creates unsigned commits - when commit.gpgsign is true, "git rebase -f" creates signed commits Signed-off-by: Nicolas Vigier <boklm@mars-attacks.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-01-05commit --amend -S: strip existing gpgsig headersLibravatar Junio C Hamano1-1/+10
Any existing commit signature was made against the contents of the old commit, including its committer date that is about to change, and will become invalid by amending it. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-12test "commit -S" and "log --show-signature"Libravatar Junio C Hamano1-0/+71
Signed-off-by: Junio C Hamano <gitster@pobox.com>