The second batch
[git] / t / t7510-signed-commit.sh
1 #!/bin/sh
2
3 test_description='signed commit tests'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
6
7 . ./test-lib.sh
8 GNUPGHOME_NOT_USED=$GNUPGHOME
9 . "$TEST_DIRECTORY/lib-gpg.sh"
10
11 test_expect_success GPG 'create signed commits' '
12         test_oid_cache <<-\EOF &&
13         header sha1:gpgsig
14         header sha256:gpgsig-sha256
15         EOF
16
17         test_when_finished "test_unconfig commit.gpgsign" &&
18
19         echo 1 >file && git add file &&
20         test_tick && git commit -S -m initial &&
21         git tag initial &&
22         git branch side &&
23
24         echo 2 >file && test_tick && git commit -a -S -m second &&
25         git tag second &&
26
27         git checkout side &&
28         echo 3 >elif && git add elif &&
29         test_tick && git commit -m "third on side" &&
30
31         git checkout main &&
32         test_tick && git merge -S side &&
33         git tag merge &&
34
35         echo 4 >file && test_tick && git commit -a -m "fourth unsigned" &&
36         git tag fourth-unsigned &&
37
38         test_tick && git commit --amend -S -m "fourth signed" &&
39         git tag fourth-signed &&
40
41         git config commit.gpgsign true &&
42         echo 5 >file && test_tick && git commit -a -m "fifth signed" &&
43         git tag fifth-signed &&
44
45         git config commit.gpgsign false &&
46         echo 6 >file && test_tick && git commit -a -m "sixth" &&
47         git tag sixth-unsigned &&
48
49         git config commit.gpgsign true &&
50         echo 7 >file && test_tick && git commit -a -m "seventh" --no-gpg-sign &&
51         git tag seventh-unsigned &&
52
53         test_tick && git rebase -f HEAD^^ && git tag sixth-signed HEAD^ &&
54         git tag seventh-signed &&
55
56         echo 8 >file && test_tick && git commit -a -m eighth -SB7227189 &&
57         git tag eighth-signed-alt &&
58
59         # commit.gpgsign is still on but this must not be signed
60         echo 9 | git commit-tree HEAD^{tree} >oid &&
61         test_line_count = 1 oid &&
62         git tag ninth-unsigned $(cat oid) &&
63         # explicit -S of course must sign.
64         echo 10 | git commit-tree -S HEAD^{tree} >oid &&
65         test_line_count = 1 oid &&
66         git tag tenth-signed $(cat oid) &&
67
68         # --gpg-sign[=<key-id>] must sign.
69         echo 11 | git commit-tree --gpg-sign HEAD^{tree} >oid &&
70         test_line_count = 1 oid &&
71         git tag eleventh-signed $(cat oid) &&
72         echo 12 | git commit-tree --gpg-sign=B7227189 HEAD^{tree} >oid &&
73         test_line_count = 1 oid &&
74         git tag twelfth-signed-alt $(cat oid)
75 '
76
77 test_expect_success GPG 'verify and show signatures' '
78         (
79                 for commit in initial second merge fourth-signed \
80                         fifth-signed sixth-signed seventh-signed tenth-signed \
81                         eleventh-signed
82                 do
83                         git verify-commit $commit &&
84                         git show --pretty=short --show-signature $commit >actual &&
85                         grep "Good signature from" actual &&
86                         ! grep "BAD signature from" actual &&
87                         echo $commit OK || exit 1
88                 done
89         ) &&
90         (
91                 for commit in merge^2 fourth-unsigned sixth-unsigned \
92                         seventh-unsigned ninth-unsigned
93                 do
94                         test_must_fail git verify-commit $commit &&
95                         git show --pretty=short --show-signature $commit >actual &&
96                         ! grep "Good signature from" actual &&
97                         ! grep "BAD signature from" actual &&
98                         echo $commit OK || exit 1
99                 done
100         ) &&
101         (
102                 for commit in eighth-signed-alt twelfth-signed-alt
103                 do
104                         git show --pretty=short --show-signature $commit >actual &&
105                         grep "Good signature from" actual &&
106                         ! grep "BAD signature from" actual &&
107                         grep "not certified" actual &&
108                         echo $commit OK || exit 1
109                 done
110         )
111 '
112
113 test_expect_success GPG 'verify-commit exits success on untrusted signature' '
114         git verify-commit eighth-signed-alt 2>actual &&
115         grep "Good signature from" actual &&
116         ! grep "BAD signature from" actual &&
117         grep "not certified" actual
118 '
119
120 test_expect_success GPG 'verify-commit exits success with matching minTrustLevel' '
121         test_config gpg.minTrustLevel ultimate &&
122         git verify-commit sixth-signed
123 '
124
125 test_expect_success GPG 'verify-commit exits success with low minTrustLevel' '
126         test_config gpg.minTrustLevel fully &&
127         git verify-commit sixth-signed
128 '
129
130 test_expect_success GPG 'verify-commit exits failure with high minTrustLevel' '
131         test_config gpg.minTrustLevel ultimate &&
132         test_must_fail git verify-commit eighth-signed-alt
133 '
134
135 test_expect_success GPG 'verify signatures with --raw' '
136         (
137                 for commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed
138                 do
139                         git verify-commit --raw $commit 2>actual &&
140                         grep "GOODSIG" actual &&
141                         ! grep "BADSIG" actual &&
142                         echo $commit OK || exit 1
143                 done
144         ) &&
145         (
146                 for commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned
147                 do
148                         test_must_fail git verify-commit --raw $commit 2>actual &&
149                         ! grep "GOODSIG" actual &&
150                         ! grep "BADSIG" actual &&
151                         echo $commit OK || exit 1
152                 done
153         ) &&
154         (
155                 for commit in eighth-signed-alt
156                 do
157                         git verify-commit --raw $commit 2>actual &&
158                         grep "GOODSIG" actual &&
159                         ! grep "BADSIG" actual &&
160                         grep "TRUST_UNDEFINED" actual &&
161                         echo $commit OK || exit 1
162                 done
163         )
164 '
165
166 test_expect_success GPG 'proper header is used for hash algorithm' '
167         git cat-file commit fourth-signed >output &&
168         grep "^$(test_oid header) -----BEGIN PGP SIGNATURE-----" output
169 '
170
171 test_expect_success GPG 'show signed commit with signature' '
172         git show -s initial >commit &&
173         git show -s --show-signature initial >show &&
174         git verify-commit -v initial >verify.1 2>verify.2 &&
175         git cat-file commit initial >cat &&
176         grep -v -e "gpg: " -e "Warning: " show >show.commit &&
177         grep -e "gpg: " -e "Warning: " show >show.gpg &&
178         grep -v "^ " cat | grep -v "^gpgsig.* " >cat.commit &&
179         test_cmp show.commit commit &&
180         test_cmp show.gpg verify.2 &&
181         test_cmp cat.commit verify.1
182 '
183
184 test_expect_success GPG 'detect fudged signature' '
185         git cat-file commit seventh-signed >raw &&
186         sed -e "s/^seventh/7th forged/" raw >forged1 &&
187         git hash-object -w -t commit forged1 >forged1.commit &&
188         test_must_fail git verify-commit $(cat forged1.commit) &&
189         git show --pretty=short --show-signature $(cat forged1.commit) >actual1 &&
190         grep "BAD signature from" actual1 &&
191         ! grep "Good signature from" actual1
192 '
193
194 test_expect_success GPG 'detect fudged signature with NUL' '
195         git cat-file commit seventh-signed >raw &&
196         cat raw >forged2 &&
197         echo Qwik | tr "Q" "\000" >>forged2 &&
198         git hash-object -w -t commit forged2 >forged2.commit &&
199         test_must_fail git verify-commit $(cat forged2.commit) &&
200         git show --pretty=short --show-signature $(cat forged2.commit) >actual2 &&
201         grep "BAD signature from" actual2 &&
202         ! grep "Good signature from" actual2
203 '
204
205 test_expect_success GPG 'amending already signed commit' '
206         git checkout fourth-signed^0 &&
207         git commit --amend -S --no-edit &&
208         git verify-commit HEAD &&
209         git show -s --show-signature HEAD >actual &&
210         grep "Good signature from" actual &&
211         ! grep "BAD signature from" actual
212 '
213
214 test_expect_success GPG 'show good signature with custom format' '
215         cat >expect <<-\EOF &&
216         G
217         13B6F51ECDDE430D
218         C O Mitter <committer@example.com>
219         73D758744BE721698EC54E8713B6F51ECDDE430D
220         73D758744BE721698EC54E8713B6F51ECDDE430D
221         EOF
222         git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
223         test_cmp expect actual
224 '
225
226 test_expect_success GPG 'show bad signature with custom format' '
227         cat >expect <<-\EOF &&
228         B
229         13B6F51ECDDE430D
230         C O Mitter <committer@example.com>
231
232
233         EOF
234         git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat forged1.commit) >actual &&
235         test_cmp expect actual
236 '
237
238 test_expect_success GPG 'show untrusted signature with custom format' '
239         cat >expect <<-\EOF &&
240         U
241         65A0EEA02E30CAD7
242         Eris Discordia <discord@example.net>
243         F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7
244         D4BE22311AD3131E5EDA29A461092E85B7227189
245         EOF
246         git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
247         test_cmp expect actual
248 '
249
250 test_expect_success GPG 'show untrusted signature with undefined trust level' '
251         cat >expect <<-\EOF &&
252         undefined
253         65A0EEA02E30CAD7
254         Eris Discordia <discord@example.net>
255         F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7
256         D4BE22311AD3131E5EDA29A461092E85B7227189
257         EOF
258         git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
259         test_cmp expect actual
260 '
261
262 test_expect_success GPG 'show untrusted signature with ultimate trust level' '
263         cat >expect <<-\EOF &&
264         ultimate
265         13B6F51ECDDE430D
266         C O Mitter <committer@example.com>
267         73D758744BE721698EC54E8713B6F51ECDDE430D
268         73D758744BE721698EC54E8713B6F51ECDDE430D
269         EOF
270         git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
271         test_cmp expect actual
272 '
273
274 test_expect_success GPG 'show unknown signature with custom format' '
275         cat >expect <<-\EOF &&
276         E
277         65A0EEA02E30CAD7
278
279
280
281         EOF
282         GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
283         test_cmp expect actual
284 '
285
286 test_expect_success GPG 'show lack of signature with custom format' '
287         cat >expect <<-\EOF &&
288         N
289
290
291
292
293         EOF
294         git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" seventh-unsigned >actual &&
295         test_cmp expect actual
296 '
297
298 test_expect_success GPG 'log.showsignature behaves like --show-signature' '
299         test_config log.showsignature true &&
300         git show initial >actual &&
301         grep "gpg: Signature made" actual &&
302         grep "gpg: Good signature" actual
303 '
304
305 test_expect_success GPG 'check config gpg.format values' '
306         test_config gpg.format openpgp &&
307         git commit -S --amend -m "success" &&
308         test_config gpg.format OpEnPgP &&
309         test_must_fail git commit -S --amend -m "fail"
310 '
311
312 test_expect_success GPG 'detect fudged commit with double signature' '
313         sed -e "/gpgsig/,/END PGP/d" forged1 >double-base &&
314         sed -n -e "/gpgsig/,/END PGP/p" forged1 | \
315                 sed -e "s/^$(test_oid header)//;s/^ //" | gpg --dearmor >double-sig1.sig &&
316         gpg -o double-sig2.sig -u 29472784 --detach-sign double-base &&
317         cat double-sig1.sig double-sig2.sig | gpg --enarmor >double-combined.asc &&
318         sed -e "s/^\(-.*\)ARMORED FILE/\1SIGNATURE/;1s/^/$(test_oid header) /;2,\$s/^/ /" \
319                 double-combined.asc > double-gpgsig &&
320         sed -e "/committer/r double-gpgsig" double-base >double-commit &&
321         git hash-object -w -t commit double-commit >double-commit.commit &&
322         test_must_fail git verify-commit $(cat double-commit.commit) &&
323         git show --pretty=short --show-signature $(cat double-commit.commit) >double-actual &&
324         grep "BAD signature from" double-actual &&
325         grep "Good signature from" double-actual
326 '
327
328 test_expect_success GPG 'show double signature with custom format' '
329         cat >expect <<-\EOF &&
330         E
331
332
333
334
335         EOF
336         git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat double-commit.commit) >actual &&
337         test_cmp expect actual
338 '
339
340
341 test_expect_success GPG 'verify-commit verifies multiply signed commits' '
342         git init multiply-signed &&
343         cd multiply-signed &&
344         test_commit first &&
345         echo 1 >second &&
346         git add second &&
347         tree=$(git write-tree) &&
348         parent=$(git rev-parse HEAD^{commit}) &&
349         git commit --gpg-sign -m second &&
350         git cat-file commit HEAD &&
351         # Avoid trailing whitespace.
352         sed -e "s/^Q//" -e "s/^Z/ /" >commit <<-EOF &&
353         Qtree $tree
354         Qparent $parent
355         Qauthor A U Thor <author@example.com> 1112912653 -0700
356         Qcommitter C O Mitter <committer@example.com> 1112912653 -0700
357         Qgpgsig -----BEGIN PGP SIGNATURE-----
358         QZ
359         Q iHQEABECADQWIQRz11h0S+chaY7FTocTtvUezd5DDQUCX/uBDRYcY29tbWl0dGVy
360         Q QGV4YW1wbGUuY29tAAoJEBO29R7N3kMNd+8AoK1I8mhLHviPH+q2I5fIVgPsEtYC
361         Q AKCTqBh+VabJceXcGIZuF0Ry+udbBQ==
362         Q =tQ0N
363         Q -----END PGP SIGNATURE-----
364         Qgpgsig-sha256 -----BEGIN PGP SIGNATURE-----
365         QZ
366         Q iHQEABECADQWIQRz11h0S+chaY7FTocTtvUezd5DDQUCX/uBIBYcY29tbWl0dGVy
367         Q QGV4YW1wbGUuY29tAAoJEBO29R7N3kMN/NEAn0XO9RYSBj2dFyozi0JKSbssYMtO
368         Q AJwKCQ1BQOtuwz//IjU8TiS+6S4iUw==
369         Q =pIwP
370         Q -----END PGP SIGNATURE-----
371         Q
372         Qsecond
373         EOF
374         head=$(git hash-object -t commit -w commit) &&
375         git reset --hard $head &&
376         git verify-commit $head 2>actual &&
377         grep "Good signature from" actual &&
378         ! grep "BAD signature from" actual
379 '
380
381 test_done