summaryrefslogtreecommitdiff
path: root/test/integration/test-apt-key
blob: d690a902670129e9ca2e71afa11449419355417c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
#!/bin/sh
set -e

# apt-key is a shell script, so relatively prune to be effected by 'crazy' things:
# confuses config parser as there exists no way of escaping " currently.
#TMPDIR="$(mktemp -d)/This is \"fü\$\$ing cràzy\", \$(man man | head -n1 | cut -d' ' -f 1)\$!"
# gpg doesn't like | in path names – documented e.g. in the man gpg2 --agent-program
#TMPDIR="$(mktemp -d)/This is fü\$\$ing cràzy, \$(man man | head -n1 | cut -d' ' -f 1)\$!"
TMPDIR_ADD="This is fü\$\$ing cràzy, \$(apt -v)\$!"

TESTDIR="$(readlink -f "$(dirname "$0")")"
. "$TESTDIR/framework"

setupenvironment
chmod o+x "${TMPWORKINGDIRECTORY}/.."
configarchitecture 'amd64'

insertpackage 'unstable' 'bar' 'i386' '1'
insertsource 'unstable' 'foo' 'all' '1'
setupaptarchive --no-update

# start from a clean plate again
cleanplate() {
	rm -rf "${ROOTDIR}/etc/apt/trusted.gpg.d/" "${ROOTDIR}/etc/apt/trusted.gpg"
	mkdir "${ROOTDIR}/etc/apt/trusted.gpg.d/"
}
testmultigpg() {
	testfailure --nomsg aptkey --quiet --readonly "$@"
	testsuccess grep "^gpgv: Can't check signature" "${ROOTDIR}/tmp/testfailure.output"
	testsuccess grep '^gpgv: Good signature from' "${ROOTDIR}/tmp/testfailure.output"
}
testaptkeyskeyring() {
	local KEYRING="$1"
	shift
	local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/aptkeylistkeyring.output"
	if ! aptkey --keyring "$KEYRING" list --with-colon 2>/dev/null | grep '^pub' | cut -d':' -f 5 > "$OUTPUT"; then
		echo -n > "$OUTPUT"
	fi
	testfileequal "$OUTPUT" "$(mapkeynametokeyid "$@")"
}
testsuccessempty() {
	testempty "$@"
}
testrun() {
	local EXT="${1:-gpg}"
	local TESTSTATE="${2:-testsuccess}"
	echo "APT::Key::ArchiveKeyring \"${KEYDIR}/joesixpack.pub.gpg\";
APT::Key::RemovedKeys \"${KEYDIR}/rexexpired.pub.gpg\";" > "${ROOTDIR}/etc/apt/apt.conf.d/aptkey.conf"

	cleanplate
	ln -sf "$(readlink -f "${KEYDIR}/joesixpack.pub.${EXT}")" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testaptkeys 'Joe Sixpack'

	${TESTSTATE} aptkey list
	msgtest 'Check that paths in list output are not' 'double-slashed'
	testfailure --nomsg grep '//' "${ROOTDIR}/tmp/${TESTSTATE}.output"

	${TESTSTATE} aptkey finger
	msgtest 'Check that paths in finger output are not' 'double-slashed'
	testfailure --nomsg grep '//' "${ROOTDIR}/tmp/${TESTSTATE}.output"

	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${KEYDIR}/joesixpack.pub.${EXT}.bak"
	if [ "$TESTSTATE" = 'testwarning' ]; then
		testwarning aptkey --fakeroot update
		testsuccess grep '^gpg: key .*DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) <joe@example.org>" not changed$' "${ROOTDIR}/tmp/testwarning.output"
		testsuccess grep '^W: .* are ignored as the file has an unsupported filetype' "${ROOTDIR}/tmp/testwarning.output"
	else
		testequalor2 'gpg: key DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) <joe@example.org>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1' 'gpg: key 5A90D141DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) <joe@example.org>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1' aptkey --fakeroot update
	fi
	testsuccess test -L "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess cmp "${KEYDIR}/joesixpack.pub.${EXT}" "${KEYDIR}/joesixpack.pub.${EXT}.bak"

	testaptkeys 'Joe Sixpack'
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg"

	${TESTSTATE} aptkey --fakeroot add "${KEYDIR}/rexexpired.pub.${EXT}"
	testfilestats "${ROOTDIR}/etc/apt/trusted.gpg" '%a' '=' '644'

	testaptkeys 'Rex Expired' 'Joe Sixpack'

	msgtest 'Check that Sixpack key can be' 'exported'
	aptkey export 'Sixpack' > "${TMPWORKINGDIRECTORY}/aptkey.export" 2>/dev/null
	aptkey --keyring "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}" exportall > "${TMPWORKINGDIRECTORY}/aptkey.exportall"
	testsuccess --nomsg cmp "${TMPWORKINGDIRECTORY}/aptkey.export" "${TMPWORKINGDIRECTORY}/aptkey.exportall"
	testsuccess test -s "${TMPWORKINGDIRECTORY}/aptkey.export"
	testsuccess test -s "${TMPWORKINGDIRECTORY}/aptkey.exportall"

	msgtest 'Execute update again to trigger removal of' 'Rex Expired key'
	${TESTSTATE} --nomsg aptkey --fakeroot update

	testaptkeys 'Joe Sixpack'

	msgtest "Try to remove a key which exists, but isn't in the" 'forced keyring'
	testsuccess --nomsg aptkey --fakeroot --keyring "${ROOTDIR}/etc/apt/trusted.gpg" del DBAC8DAE

	testaptkeys 'Joe Sixpack'

	${TESTSTATE} aptkey --fakeroot del DBAC8DAE
	"${TESTSTATE}empty" aptkey list

	ln -sf "$(readlink -f "${KEYDIR}/joesixpack.pub.${EXT}")" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testaptkeys 'Joe Sixpack'
	msgtest "Remove a key from" 'forced keyring in trusted.d.gpg'
	testsuccess --nomsg aptkey --fakeroot --keyring "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}" del DBAC8DAE
	testsuccess cmp -s "$(readlink -f "${KEYDIR}/joesixpack.pub.${EXT}")" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"
	"${TESTSTATE}empty" aptkey list

	cp -a "${KEYDIR}/marvinparanoid.pub.asc" "${ROOTDIR}/etc/foobar.pub"
	testsuccess aptkey --fakeroot --keyring "${ROOTDIR}/etc/foobar.pub" add "${KEYDIR}/rexexpired.pub.asc" "${KEYDIR}/joesixpack.pub.gpg"
	testfilestats "${ROOTDIR}/etc/foobar.pub" '%a' '=' '644'
	testaptkeyskeyring "${ROOTDIR}/etc/foobar.pub" 'Marvin Paranoid' 'Rex Expired' 'Joe Sixpack'
	"${TESTSTATE}empty" aptkey list

	msgtest 'Test key removal with' 'lowercase key ID' #keylength somewhere between 8byte and short
	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del d141dbac8dae
	"${TESTSTATE}empty" aptkey list

	if [ "$(id -u)" != '0' ]; then
		msgtest 'Test key removal with' 'unreadable key'
		cleanplate
		cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
		echo 'foobar' > "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
		chmod 000 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
		testwarning --nomsg aptkey --fakeroot del d141dbac8dae
		testwarning aptkey list
		chmod 644 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
		rm -f "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
		grep -v '^W: ' "${ROOTDIR}/tmp/testwarning.output" > "${ROOTDIR}/aptkeylist.output" || true
		testempty cat "${ROOTDIR}/aptkeylist.output"
	fi

	msgtest 'Test key removal with' 'single key in real file'
	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del DBAC8DAE
	"${TESTSTATE}empty" aptkey list
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess cmp "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"

	msgtest 'Test key removal with' 'different key specs'
	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	cp -a "${KEYDIR}/marvinparanoid.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/marvinparanoid.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del 0xDBAC8DAE 528144E2
	"${TESTSTATE}empty" aptkey list
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess cmp "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/marvinparanoid.${EXT}"
	testsuccess cmp "${KEYDIR}/marvinparanoid.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/marvinparanoid.${EXT}~"

	msgtest 'Test key removal with' 'long key ID'
	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del 5A90D141DBAC8DAE
	"${TESTSTATE}empty" aptkey list
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess cmp "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"

	msgtest 'Test key removal with' 'fingerprint'
	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE
	"${TESTSTATE}empty" aptkey list
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess cmp "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"

	msgtest 'Test key removal with' 'spaced fingerprint'
	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del '34A8 E9D1 8DB3 20F3 67E8 EAA0 5A90 D141 DBAC 8DAE'
	"${TESTSTATE}empty" aptkey list
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess cmp "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"

	msgtest 'Test key removal with' 'single key in softlink'
	cleanplate
	ln -sf "$(readlink -f "${KEYDIR}/joesixpack.pub.${EXT}")" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del DBAC8DAE
	"${TESTSTATE}empty" aptkey list
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess test -L "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"

	cleanplate
	${TESTSTATE} aptkey --fakeroot add "${KEYDIR}/joesixpack.pub.${EXT}"
	ln -sf "$(readlink -f "${KEYDIR}/marvinparanoid.pub.${EXT}")" "${KEYDIR}/marvin paránöid.pub.${EXT}"
	${TESTSTATE} aptkey --fakeroot add "${KEYDIR}/marvin paránöid.pub.${EXT}"
	testaptkeys 'Joe Sixpack' 'Marvin Paranoid'
	cp -a "${ROOTDIR}/etc/apt/trusted.gpg" "${KEYDIR}/testcase-multikey.pub.gpg" # store for reuse
	aptkey --keyring "${KEYDIR}/testcase-multikey.pub.gpg" export > "${KEYDIR}/testcase-multikey.pub.asc"

	msgtest 'Test key removal with' 'multi key in real file'
	cleanplate
	cp -a "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del DBAC8DAE
	testaptkeys 'Marvin Paranoid'
	testsuccess cmp "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}~"

	msgtest 'Test key removal with' 'multi key in softlink'
	cleanplate
	ln -s "$(readlink -f "${KEYDIR}/testcase-multikey.pub.${EXT}")" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del DBAC8DAE
	testaptkeys 'Marvin Paranoid'
	testsuccess cmp "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}~"
	testfailure test -L "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}"
	testsuccess test -L "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}~"

	msgtest 'Test key removal with' 'multiple files including key'
	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	cp -a "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}"
	${TESTSTATE} --nomsg aptkey --fakeroot del DBAC8DAE
	testaptkeys 'Marvin Paranoid'
	testfailure test -e "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	testsuccess cmp "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}~"
	testsuccess cmp "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}~"

	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	cp -a "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}"
	testaptkeys 'Joe Sixpack' 'Joe Sixpack' 'Marvin Paranoid'
	msgtest 'Test merge-back of' 'added keys'
	${TESTSTATE} --nomsg aptkey adv --batch --yes --import "${KEYDIR}/rexexpired.pub.${EXT}"
	testaptkeys 'Rex Expired' 'Joe Sixpack' 'Joe Sixpack' 'Marvin Paranoid'

	msgtest 'Test merge-back of' 'removed keys'
	${TESTSTATE} --nomsg aptkey adv --batch --yes --delete-keys 27CE74F9
	testaptkeys 'Joe Sixpack' 'Joe Sixpack' 'Marvin Paranoid'

	msgtest 'Test merge-back of' 'removed duplicate keys'
	${TESTSTATE} --nomsg aptkey adv --batch --yes --delete-keys DBAC8DAE
	testaptkeys 'Marvin Paranoid'

	cleanplate
	cp -a "${KEYDIR}/joesixpack.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.${EXT}"
	cp -a "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}"
	local SIGNATURE="${TMPWORKINGDIRECTORY}/signature"
	msgtest 'Test signing a file' 'with a key'
	echo 'Verify me. This is my signature.' > "$SIGNATURE"
	echo 'lalalalala' > "${SIGNATURE}2"
	testsuccess --nomsg aptkey --quiet --keyring "${KEYDIR}/marvinparanoid.pub.gpg" --secret-keyring "${KEYDIR}/marvinparanoid.sec" --readonly \
		adv --batch --yes --default-key 'Marvin' --armor --detach-sign --sign --output "${SIGNATURE}.gpg" "${SIGNATURE}"
	testsuccess test -s "${SIGNATURE}.gpg" -a -s "${SIGNATURE}"

	msgtest 'Test verify a file' 'with no sig'
	testfailure --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/testcase-multikey.pub.${EXT}" verify "${SIGNATURE}" "${SIGNATURE}2"

	for GPGV in '' 'gpgv' 'gpgv1' 'gpgv2'; do
		echo "APT::Key::GPGVCommand \"$GPGV\";" > "${ROOTDIR}/etc/apt/apt.conf.d/00gpgvcmd"
		if [ -n "$GPGV" ] && ! command dpkg -l gnupg1 2>&1 | grep -q '^ii'; then continue; fi

		msgtest 'Test verify a file' 'with all keys'
		${TESTSTATE} --nomsg aptkey --quiet --readonly verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		if [ "$(id -u)" != '0' ]; then
			msgtest 'Test verify a file' 'with unreadable key'
			echo 'foobar' > "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
			chmod 000 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
			testwarning --nomsg aptkey --quiet --readonly verify "${SIGNATURE}.gpg" "${SIGNATURE}"
			testwarning aptkey list
			# check that apt users see warnings, too
			rm -rf "${ROOTDIR}/var/lib/apt/lists"
			testwarning apt update

			chmod 644 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
			rm -f "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.${EXT}"
		fi

		msgtest 'Test verify a file' 'with good keyring'
		testsuccess --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/testcase-multikey.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a file' 'with bad keyring'
		testfailure --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/joesixpack.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a file' 'with non-existing keyring'
		testfailure --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/does-not-exist.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"
		testfailure test -e "${KEYDIR}/does-not-exist.pub.${EXT}"

		# note: this isn't how apts gpgv method implements keyid for verify
		msgtest 'Test verify a file' 'with good keyid'
		${TESTSTATE} --nomsg aptkey --quiet --readonly --keyid 'Paranoid' verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a file' 'with bad keyid'
		testfailure --nomsg aptkey --quiet --readonly --keyid 'Sixpack' verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a file' 'with non-existing keyid'
		testfailure --nomsg aptkey --quiet --readonly --keyid 'Kalnischkies' verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test verify fails on' 'bad file'
		testfailure --nomsg aptkey --quiet --readonly verify "${SIGNATURE}.gpg" "${SIGNATURE}2"

		# try to perform an entire update with this gpgv
		rm -rf "${ROOTDIR}/var/lib/apt/lists"
		${TESTSTATE} apt update -o Test::Dir="${ROOTDIR}"
	done
	rm -f "${ROOTDIR}/etc/apt/apt.conf.d/00gpgvcmd"

	msgtest 'Test verify a file' 'with good keyring'
	testsuccess --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/testcase-multikey.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"

	cleanplate
	cat "${KEYDIR}/joesixpack.pub.gpg" "${KEYDIR}/marvinparanoid.pub.gpg" > "${KEYDIR}/double.pub.gpg"
	cat "${KEYDIR}/joesixpack.pub.asc" "${KEYDIR}/marvinparanoid.pub.asc" > "${KEYDIR}/double.pub.asc"
	cat "${KEYDIR}/joesixpack.sec" "${KEYDIR}/marvinparanoid.sec" > "${KEYDIR}/double.sec"
	cp -a "${KEYDIR}/double.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/double.${EXT}"
	cp -a "${KEYDIR}/testcase-multikey.pub.${EXT}" "${ROOTDIR}/etc/apt/trusted.gpg.d/multikey.${EXT}"
	rm -f "${SIGNATURE}.gpg"
	testsuccess aptkey --quiet --keyring "${KEYDIR}/double.pub.gpg" --secret-keyring "${KEYDIR}/double.sec" --readonly \
		adv --batch --yes -u 'Marvin' -u 'Joe' --armor --detach-sign --sign --output "${SIGNATURE}.gpg" "${SIGNATURE}"
	testsuccess test -s "${SIGNATURE}.gpg" -a -s "${SIGNATURE}"

	for GPGV in '' 'gpgv' 'gpgv1' 'gpgv2'; do
		echo "APT::Key::GPGVCommand \"$GPGV\";" > "${ROOTDIR}/etc/apt/apt.conf.d/00gpgvcmd"
		if [ -n "$GPGV" ] && ! command dpkg -l gnupg1 2>&1 | grep -q '^ii'; then continue; fi

		msgtest 'Test verify a doublesigned file' 'with all keys'
		${TESTSTATE} --nomsg aptkey --quiet --readonly verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test verify a doublesigned file' 'with good keyring joe'
		testmultigpg --keyring "${KEYDIR}/joesixpack.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test verify a doublesigned file' 'with good keyring marvin'
		testmultigpg --keyring "${KEYDIR}/marvinparanoid.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a doublesigned file' 'with bad keyring'
		testfailure --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/rexexpired.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a doublesigned file' 'with non-existing keyring'
		testfailure --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/does-not-exist.pub.${EXT}" verify "${SIGNATURE}.gpg" "${SIGNATURE}"
		testfailure test -e "${KEYDIR}/does-not-exist.pub.${EXT}"

		# note: this isn't how apts gpgv method implements keyid for verify
		msgtest 'Test verify a doublesigned file' 'with good keyid'
		testmultigpg --keyid 'Paranoid' verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a doublesigned file' 'with bad keyid'
		testfailure --nomsg aptkey --quiet --readonly --keyid 'Rex' verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test fail verify a doublesigned file' 'with non-existing keyid'
		testfailure --nomsg aptkey --quiet --readonly --keyid 'Kalnischkies' verify "${SIGNATURE}.gpg" "${SIGNATURE}"

		msgtest 'Test verify fails on' 'bad doublesigned file'
		testfailure --nomsg aptkey --quiet --readonly verify "${SIGNATURE}.gpg" "${SIGNATURE}2"
	done
	rm -f "${ROOTDIR}/etc/apt/apt.conf.d/00gpgvcmd"
}

setupgpgcommand() {
	local GPGEXE;
	if command dpkg -l gnupg1 2>&1 | grep -q '^ii'; then
		if [ "$1" = '1' ]; then
			GPGEXE='gpg1'
		else
			GPGEXE='gpg'
		fi
	else
		if [ "$1" = '1' ]; then
			GPGEXE='gpg'
		else
			GPGEXE='gpg2'
		fi
	fi
	msgmsg 'Force tests to be run with' "$GPGEXE"
	echo "APT::Key::GPGCommand \"$GPGEXE\";" > "${ROOTDIR}/etc/apt/apt.conf.d/00gpgcmd"
	testsuccess aptkey --readonly adv --version
	cp "${ROOTDIR}/tmp/testsuccess.output" "${TMPWORKINGDIRECTORY}/aptkey.version"
	testsuccess grep "^gpg (GnuPG) $1\." "${TMPWORKINGDIRECTORY}/aptkey.version"
}

(cd /; find "${TMPWORKINGDIRECTORY}/keys" -name '*.pub' -type f) | while read trusted; do
	testsuccess aptkey --keyring "$trusted" adv --armor --export --output "${trusted}.asc"
	cp -a "$trusted" "${trusted}.gpg"
done

# run with default (whatever this is) in current CWD with relative paths
ROOTDIR="./rootdir"
KEYDIR="./keys"
testrun

# run with … and up the game with a strange CWD & absolute paths
ROOTDIR="${TMPWORKINGDIRECTORY}/rootdir"
KEYDIR="${TMPWORKINGDIRECTORY}/keys"
mkdir inaccessible
cd inaccessible
chmod 600 ../inaccessible
testfilestats "${TMPWORKINGDIRECTORY}/inaccessible" '%a' '=' '600'

setupgpgcommand '1'
testrun
setupgpgcommand '2'
testrun

msgmsg 'Tests to be run with' 'asc files'
rm -f "${ROOTDIR}/etc/apt/apt.conf.d/00gpgcmd"
testrun 'asc'

msgmsg 'Tests to be run with' 'bad files'
# don't let the plate be so clean anymore
cleanplate() {
	rm -rf "${ROOTDIR}/etc/apt/trusted.gpg.d/" "${ROOTDIR}/etc/apt/trusted.gpg"
	mkdir "${ROOTDIR}/etc/apt/trusted.gpg.d/"
	touch "${ROOTDIR}/etc/apt/trusted.gpg.d/emptyfile.gpg"
	touch "${ROOTDIR}/etc/apt/trusted.gpg.d/emptyfile.asc"
	echo 'broken' > "${ROOTDIR}/etc/apt/trusted.gpg.d/brokenfile.gpg"
	echo 'broken' > "${ROOTDIR}/etc/apt/trusted.gpg.d/brokenfile.asc"
}
testrun 'gpg' 'testwarning'