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