Merge ~nacc/git-ubuntu:apt-repo into git-ubuntu:master

Proposed by Nish Aravamudan
Status: Superseded
Proposed branch: ~nacc/git-ubuntu:apt-repo
Merge into: git-ubuntu:master
Diff against target: 1380 lines (+1169/-0)
33 files modified
MANIFEST.in (+1/-0)
gitubuntu/apt_repo.py (+259/-0)
gitubuntu/apt_repo_test.py (+210/-0)
gitubuntu/apt_repo_test/README (+24/-0)
gitubuntu/apt_repo_test/attacker-privkey.asc (+105/-0)
gitubuntu/apt_repo_test/attacker-pubkey.asc (+52/-0)
gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/InRelease (+38/-0)
gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 (+1/-0)
gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release (+2/-0)
gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release.gpg (+16/-0)
gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release (+2/-0)
gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release.gpg (+16/-0)
gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release (+18/-0)
gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release.gpg (+16/-0)
gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 (+1/-0)
gitubuntu/apt_repo_test/inline.attackersig/dists/bionic/InRelease (+21/-0)
gitubuntu/apt_repo_test/inline.badsig/dists/bionic/InRelease (+21/-0)
gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/InRelease (+38/-0)
gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 (+1/-0)
gitubuntu/apt_repo_test/inline.injection/dists/bionic/InRelease (+37/-0)
gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/InRelease (+37/-0)
gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/main/source/Sources (+1/-0)
gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release (+13/-0)
gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release.gpg (+16/-0)
gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/main/source/Sources (+1/-0)
gitubuntu/apt_repo_test/nosig.bare/dists/bionic/Release (+1/-0)
gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release (+1/-0)
gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release.gpg (+0/-0)
gitubuntu/apt_repo_test/nosig.inline/dists/bionic/InRelease (+1/-0)
gitubuntu/apt_repo_test/nothing/README (+4/-0)
gitubuntu/apt_repo_test/privkey.asc (+105/-0)
gitubuntu/apt_repo_test/pubkey.asc (+51/-0)
snap/snapcraft.yaml (+59/-0)
Reviewer Review Type Date Requested Status
Robie Basak Pending
Review via email: mp+340068@code.launchpad.net

Description of the change

Make jenkins happy

To post a comment you must log in.

Unmerged commits

aa014cb... by Nish Aravamudan

snap: re-add gnupg2 for gpgv

The apt_repo code relies on gpgv being callable in the snap, but needs
the version in Bionic (which added the `gpgv --output` option). Do not
ship anything else from gnupg2.

Revert "Revert "snap: build gpg from source""

This reverts commit 3294bc6d6c93c8c76f953266f9665ede78c5937d.

a74564f... by Robie Basak

Add gitubuntu/apt_repo_test/ to the snap

This is needed for the in-snap self test.

a72b7b2... by Robie Basak

Add apt_repo module

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/MANIFEST.in b/MANIFEST.in
2index 35cac97..ac8ce4e 100644
3--- a/MANIFEST.in
4+++ b/MANIFEST.in
5@@ -1,3 +1,4 @@
6 include gitubuntu/*.txt
7 include gitubuntu/hooks/*
8+graft gitubuntu/apt_repo_test
9 graft gitubuntu/changelog_tests
10diff --git a/gitubuntu/apt_repo.py b/gitubuntu/apt_repo.py
11new file mode 100644
12index 0000000..3eef4a4
13--- /dev/null
14+++ b/gitubuntu/apt_repo.py
15@@ -0,0 +1,259 @@
16+import errno
17+import functools
18+import hashlib
19+import os
20+import subprocess
21+import tempfile
22+import urllib.request
23+
24+import debian.deb822
25+
26+# This file is security sensitive since it deals with untrusted inputs. To keep
27+# it easier to verify, please avoid dependencies on other parts of the project
28+# and keep the code separate in this module (ie. don't tangle it with other
29+# non-security-sensitive code).
30+
31+
32+DEFAULT_TRUSTED_KEYRING_PATHS = [
33+ '/usr/share/keyrings/debian-archive-keyring.gpg',
34+ '/usr/share/keyrings/debian-archive-removed-keys.gpg',
35+ '/usr/share/keyrings/ubuntu-archive-keyring.gpg',
36+ '/usr/share/keyrings/ubuntu-archive-removed-keys.gpg',
37+]
38+HASH = 'SHA256'
39+HASH_FUNC = lambda x: hashlib.sha256(x).hexdigest()
40+
41+# 16 MiB to prevent DoS; current InRelease is ~256 kiB. This is only used for
42+# Release{.gpg} and InRelease files. Once we have the release file and have
43+# validated it, the size of other files are known and authenticated.
44+MAX_RELEASE_FETCH = 1024*1024*16
45+
46+
47+class RepositoryNotFoundError(RuntimeError): pass
48+class SignatureVerificationError(RuntimeError): pass
49+class HashVerificationError(RuntimeError): pass
50+
51+
52+def _maybe_fetch_release_url(url):
53+ """Return bytes of a release file URL, or None if not found.
54+
55+ :param str url: Release file URL
56+ :rtype: bytes
57+
58+ Any exceptions from the underlying urllib calls, apart from file not found
59+ errors, are passed through without modification.
60+
61+ A urllib exception that represents a file not found error is returned as
62+ None.
63+ """
64+ try:
65+ # Do not read more than a reasonable amount to prevent a memory DoS
66+ data = urllib.request.urlopen(url).read(MAX_RELEASE_FETCH)
67+ except urllib.error.HTTPError as e:
68+ if e.code == 404:
69+ return None
70+ raise
71+ except urllib.error.URLError as e:
72+ if isinstance(e.reason, FileNotFoundError):
73+ return None
74+ raise
75+ else:
76+ return data
77+
78+
79+def _write_file_bytes(path, data):
80+ """Write the given data to a file path.
81+
82+ :param str path: filesystem path to write to.
83+ :param bytes data: data to write.
84+ :rtype None
85+ """
86+ with open(path, 'wb') as f:
87+ f.write(data)
88+
89+
90+def _verify(
91+ unverified_data,
92+ detached_signature=None,
93+ trusted_keyring_paths=None,
94+):
95+ """Verify a signature on some data.
96+
97+ :param bytes unverified_data: data to verify, which may include an inline
98+ signature.
99+ :param bytes detached_signature: detached signature data, or None if the
100+ signature is expected inline.
101+ :param list(str) trusted_keyring_paths: filesystem paths to gpg keyrings to
102+ trust. If the data has been signed by a key in one of these keyrings
103+ and the signature is valid, the data is immediately treated as
104+ verified, regardless of key signatures or trust paths. Defaults to
105+ DEFAULT_TRUSTED_KEYRING_PATHS defined elsewhere in this module.
106+ :rtype: bytes
107+ :returns: the verified data. This should be used by the caller in favour of
108+ the input data as clearsigned data can include unverified parts.
109+ :raises SignatureVerificationError: on signature validation failure or some
110+ other problem with gpgv.
111+ :raises RuntimeError: if gpgv does not produce the verified output from an
112+ inline signature.
113+ """
114+ trusted_keyring_paths = (
115+ trusted_keyring_paths or DEFAULT_TRUSTED_KEYRING_PATHS
116+ )
117+ with tempfile.TemporaryDirectory() as tmpdir:
118+ unverified_data_path = os.path.join(tmpdir, 'unverified-data')
119+ verified_data_path = os.path.join(tmpdir, 'verified-data')
120+ _write_file_bytes(unverified_data_path, unverified_data)
121+ if detached_signature is None:
122+ args = [unverified_data_path]
123+ else:
124+ sig_path = os.path.join(tmpdir, 'sig')
125+ _write_file_bytes(sig_path, detached_signature)
126+ args = [sig_path, unverified_data_path]
127+ cmd = [
128+ 'gpgv',
129+ '-q',
130+ '--output', verified_data_path,
131+ ] + [
132+ '--keyring=%s' % keyring
133+ for keyring in trusted_keyring_paths
134+ ] + args
135+ try:
136+ subprocess.check_call(cmd)
137+ except subprocess.CalledProcessError:
138+ raise SignatureVerificationError()
139+
140+ # The data has been verified at this point. Now we return the data that
141+ # was actually verified.
142+
143+ if os.path.exists(verified_data_path):
144+ # The verified data has been supplied by the gpgv command to the
145+ # file given by the --output option.
146+ with open(verified_data_path, 'rb') as f:
147+ return f.read()
148+ elif detached_signature is not None:
149+ # gpgv 2.2.4-1ubuntu1 seems to have a bug (or difference from
150+ # documentation) in that using --output returns nothing in the case
151+ # of a detached signature. But if we have a detached signature, all
152+ # of the unverified data has been guaranteed to be verified when
153+ # gpgv returns an exit status of 0. We can therefore just return
154+ # the unverified data that we just verified.
155+ return unverified_data
156+ else:
157+ # gpg 2.1.15-1ubuntu8 seems to have a bug that --output does
158+ # nothing, including for clearsigned signatures. gpgv in the same
159+ # version has no defined --output option. In this case we have no
160+ # way of determining which part of the input file was verified,
161+ # since it may not all have been signed (before and after the text
162+ # markers for example). So we cannot treat anything as verified.
163+ # This bug is reported to have been fixed upstream in 2.1.16 and
164+ # --output added to gpgv there. This exception should not be raised
165+ # with a newer version of gpgv (at least 2.1.16 according to
166+ # upstream NEWS, and verified working in 2.2.4-1ubuntu1).
167+ raise RuntimeError(
168+ "gpgv did not return verified data in --output and so the "
169+ "verified part of the clearsigned data is not available"
170+ )
171+
172+
173+class Release:
174+ def __init__(self, suite_url, verified_release_data):
175+ """Not to be called directly. Use Release.from_base_url().
176+
177+ :param str suite_url: the URL of the top level of the suite.
178+ :param bytes verified_release_data: the contents of the Release file,
179+ which must already have had its signature validated.
180+ """
181+ self.suite_url = suite_url
182+ self.deb822 = debian.deb822.Release(verified_release_data.splitlines())
183+ assert HASH in self.deb822
184+ self.files = {
185+ entry['name']: (entry[HASH], int(entry['size']))
186+ for entry in self.deb822[HASH]
187+ }
188+
189+ @classmethod
190+ def from_base_url(cls, base_url, suite, trusted_keyring_paths=None):
191+ """Fetch Release file, validate it and instantiate a Release instance.
192+
193+ :param str base_url: the top level of the apt repository. For example:
194+ 'http://archive.ubuntu.com/ubuntu'
195+ :param str suite: the name of the suite. Examples: 'bionic',
196+ 'trusty-proposed'.
197+ :rtype Release
198+ :raises SignatureValidationError: if a repository is found with a bad
199+ signature.
200+ :raises RepositoryNotFound: if a (signed) repository cannot be found.
201+ """
202+ suite_url = "%s/dists/%s" % (base_url, suite)
203+ in_release_url = "%s/InRelease" % suite_url
204+ release_url = "%s/Release" % suite_url
205+ release_sig_url = "%s/Release.gpg" % suite_url
206+
207+ unverified_release_data = _maybe_fetch_release_url(in_release_url)
208+ if unverified_release_data is None:
209+ unverified_release_data = _maybe_fetch_release_url(release_url)
210+ if unverified_release_data is None:
211+ raise RepositoryNotFoundError(
212+ "Release file not found at %s" % release_url,
213+ )
214+ release_data_sig = _maybe_fetch_release_url(release_sig_url)
215+ if release_data_sig is None:
216+ raise RepositoryNotFoundError(
217+ "Release file sig not found at %s" % release_sig_url,
218+ )
219+ verified_release_data = _verify(
220+ unverified_release_data,
221+ release_data_sig,
222+ trusted_keyring_paths=trusted_keyring_paths,
223+ )
224+ else:
225+ verified_release_data = _verify(
226+ unverified_release_data,
227+ trusted_keyring_paths=trusted_keyring_paths,
228+ )
229+
230+ return cls(suite_url, verified_release_data)
231+
232+ @property
233+ def by_hash(self):
234+ """Whether or not by-hash is available on this suite.
235+
236+ :rtype bool
237+ """
238+ return bool(self.deb822.get('Acquire-By-Hash', False))
239+
240+ def _get_file_url(self, name):
241+ """Obtain full URL for a particular file
242+
243+ :param str name: file name
244+ :rtype str
245+ """
246+ file_hash, file_size = self.files[name]
247+ if self.by_hash:
248+ # Contents files live at URLs like
249+ # http://archive.ubuntu.com/ubuntu/dists/bionic/by-hash/SHA256/
250+ # and are requested with name='Contents-amd64.gz'
251+ # Sources files live at URLs like
252+ # http://archive.ubuntu.com/ubuntu/dists/bionic/main/source/by-hash/SHA256/
253+ # and are requested with name='main/source/Sources.gz'
254+ # so we want to extract the dirname of name
255+ name_head, name_tail = os.path.split(name)
256+ url_parts = [self.suite_url, name_head, 'by-hash', HASH, file_hash]
257+ else:
258+ url_parts = [self.suite_url, name]
259+ # skip empty parts, e.g. name_head above
260+ url = '/'.join(x for x in url_parts if x)
261+ return url
262+
263+ def get_file_bytes(self, name):
264+ file_hash, file_size = self.files[name]
265+ url = self._get_file_url(name)
266+
267+ # Do not read more than the expected file size to prevent a memory DoS
268+ data = urllib.request.urlopen(url).read(file_size)
269+ if HASH_FUNC(data) != file_hash:
270+ raise HashVerificationError()
271+ return data
272+
273+ def has_file(self, name):
274+ return name in self.files
275diff --git a/gitubuntu/apt_repo_test.py b/gitubuntu/apt_repo_test.py
276new file mode 100644
277index 0000000..3488125
278--- /dev/null
279+++ b/gitubuntu/apt_repo_test.py
280@@ -0,0 +1,210 @@
281+import itertools
282+import os
283+import subprocess
284+import tempfile
285+import unittest.mock
286+import urllib.error
287+
288+import pkg_resources
289+import pytest
290+
291+import gitubuntu.apt_repo as target
292+
293+
294+@pytest.fixture(scope='session')
295+def trustedkeys():
296+ with tempfile.TemporaryDirectory() as tmp_path:
297+ env = dict(os.environ)
298+ env['GNUPGHOME'] = tmp_path
299+ trustedkeys_path = os.path.join(tmp_path, 'trustedkeys.gpg')
300+ subprocess.check_call(
301+ [
302+ 'gpg',
303+ '--no-default-keyring',
304+ '--keyring', trustedkeys_path,
305+ '--import',
306+ pkg_resources.resource_filename(
307+ 'gitubuntu', 'apt_repo_test/pubkey.asc'
308+ ),
309+ ],
310+ env=env,
311+ )
312+ yield trustedkeys_path
313+
314+
315+EXPECTED_REPOSITORY_NOT_FOUND_ERROR = [
316+ 'nosig.bare',
317+ 'nothing',
318+]
319+
320+EXPECTED_SIGNATURE_VERIFICATION_ERROR = [
321+ 'nosig.detached-empty',
322+ 'nosig.inline',
323+ 'inline.attackersig',
324+ 'inline.badsig',
325+ 'detached.badsig',
326+ 'detached.attackersig',
327+]
328+
329+EXPECTED_HASH_VERIFICATION_ERROR = [
330+ 'by-hash.badfile',
331+ 'no-hash.badfile',
332+]
333+
334+EXPECTED_SUCCESS = [
335+ 'detached.by-hash',
336+ 'inline.by-hash',
337+ 'inline.no-hash',
338+]
339+
340+SEPARATELY_TESTED = [
341+ 'inline.injection', # test_no_injection
342+]
343+
344+ALL_TEMPLATES_TESTED = frozenset(itertools.chain(
345+ EXPECTED_SUCCESS,
346+ EXPECTED_REPOSITORY_NOT_FOUND_ERROR,
347+ EXPECTED_SIGNATURE_VERIFICATION_ERROR,
348+ EXPECTED_HASH_VERIFICATION_ERROR,
349+ SEPARATELY_TESTED,
350+))
351+
352+
353+def test_all_examples_covered():
354+ # Check that we have a test for every example apt repository provided in
355+ # gitubuntu/apt_repo_test/. All directories under there are assumed to be
356+ # apt repository examples. If there's a directory not listed in
357+ # ALL_TEMPLATES_TESTED, then we must accidentally not be testing it.
358+ examples_path = pkg_resources.resource_filename(
359+ 'gitubuntu',
360+ 'apt_repo_test',
361+ )
362+ for basename in os.listdir(examples_path):
363+ example_path = os.path.join(examples_path, basename)
364+ assert (
365+ not os.path.isdir(example_path) or basename in ALL_TEMPLATES_TESTED
366+ )
367+
368+
369+def get_example_url(example_name):
370+ return ''.join([
371+ 'file://',
372+ pkg_resources.resource_filename('gitubuntu', 'apt_repo_test'),
373+ '/',
374+ example_name,
375+ ])
376+
377+
378+def get_release_obj(trustedkeys, example_name):
379+ return target.Release.from_base_url(
380+ get_example_url(example_name),
381+ suite='bionic',
382+ trusted_keyring_paths=[trustedkeys],
383+ )
384+
385+
386+@pytest.mark.parametrize('example_name', EXPECTED_SUCCESS)
387+def test_success(trustedkeys, example_name):
388+ release = get_release_obj(trustedkeys, example_name)
389+ contents = release.get_file_bytes('main/source/Sources').decode()
390+ assert contents == "sources-content\n"
391+
392+
393+@pytest.mark.parametrize('example_name', EXPECTED_REPOSITORY_NOT_FOUND_ERROR)
394+def test_nosig(trustedkeys, example_name):
395+ with pytest.raises(target.RepositoryNotFoundError):
396+ release = get_release_obj(trustedkeys, example_name)
397+
398+
399+@pytest.mark.parametrize('example_name', EXPECTED_SIGNATURE_VERIFICATION_ERROR)
400+def test_badsig(trustedkeys, example_name):
401+ with pytest.raises(target.SignatureVerificationError):
402+ release = get_release_obj(trustedkeys, example_name)
403+
404+
405+@pytest.mark.parametrize('example_name', EXPECTED_HASH_VERIFICATION_ERROR)
406+def test_badfile(trustedkeys, example_name):
407+ release = get_release_obj(trustedkeys, example_name)
408+ with pytest.raises(target.HashVerificationError):
409+ release.get_file_bytes('main/source/Sources')
410+
411+
412+def test_no_injection(trustedkeys):
413+ release = get_release_obj(trustedkeys, 'inline.injection')
414+ assert 'Injected' not in release.deb822
415+
416+
417+def test_has_file(trustedkeys):
418+ release = get_release_obj(trustedkeys, 'inline.by-hash')
419+ assert release.has_file('main/source/Sources')
420+ assert not release.has_file('nonexistent')
421+
422+
423+def test_max_release_fetch_size(tmpdir):
424+ # Check that maybe_fetch_release_url really does limit the size of the data
425+ # read. We do this by creating a local URL that has more data than the size
426+ # limit. The test data size is deliberately hardcoded here to protect
427+ # against accidental changes to the constant in the code under test. If the
428+ # constant ever needs to be increased, then the value hardcoded in this
429+ # test will also need to be changed.
430+ #
431+ # If the maybe_fetch_release_url is ever factored out, a new test should be
432+ # written to replace this test to ensure that the refactored code is not
433+ # vulnerable to a resource exhaustion DoS.
434+ large_data = (17 * 1024 * 1024) * b'x'
435+ bigfile_path = str(tmpdir.join('bigfile'))
436+ with open(bigfile_path, 'wb') as fobj:
437+ fobj.write(large_data)
438+ fobj.close()
439+ bigfile_url = "file://" + os.path.abspath(bigfile_path)
440+ read_data = target._maybe_fetch_release_url(bigfile_url)
441+ assert len(read_data) < len(large_data)
442+
443+
444+# Cases where maybe_fetch_release_url should return None (404 in the case of an
445+# http:// or https:// URL, and FileNotFoundError for a file:// URL)
446+@pytest.mark.parametrize('exception', [
447+ (urllib.error.HTTPError(
448+ url=None,
449+ code=404,
450+ msg=None,
451+ hdrs=None,
452+ fp=None,
453+ )),
454+ (urllib.error.URLError(reason=FileNotFoundError())),
455+])
456+@unittest.mock.patch('urllib.request.urlopen')
457+def test_maybe_fetch_release_url_not_found(mock_urlopen, exception):
458+ mock_urlopen().read.side_effect = exception
459+ assert target._maybe_fetch_release_url(None) is None
460+
461+
462+# Cases where maybe_fetch_release_url should pass through the exception (an
463+# HTTPError where the response is not a 404, a URLError where the reason isn't
464+# FileNotFoundError, and for any other exception).
465+@pytest.mark.parametrize('exception', [
466+ (urllib.error.HTTPError(
467+ url=None,
468+ code=403,
469+ msg=None,
470+ hdrs=None,
471+ fp=None,
472+ )),
473+ (urllib.error.URLError(reason=None)),
474+ (Exception()),
475+])
476+@unittest.mock.patch('urllib.request.urlopen')
477+def test_maybe_fetch_release_url_other_error(mock_urlopen, exception):
478+ mock_urlopen().read.side_effect = exception
479+ with pytest.raises(type(exception)):
480+ target._maybe_fetch_release_url(None)
481+
482+
483+# If subprocess.check_call does nothing, that is like running gpgv that returns
484+# an exit status of 0 but doesn't write anything to the path specified by
485+# --output. In the case of an inline signature, this should raise a
486+# RuntimeError.
487+@unittest.mock.patch('subprocess.check_call')
488+def test_gpgv_no_output(trustedkeys):
489+ with pytest.raises(RuntimeError):
490+ target._verify(b'', trusted_keyring_paths=trustedkeys)
491diff --git a/gitubuntu/apt_repo_test/README b/gitubuntu/apt_repo_test/README
492new file mode 100644
493index 0000000..59f4763
494--- /dev/null
495+++ b/gitubuntu/apt_repo_test/README
496@@ -0,0 +1,24 @@
497+GnuPG demands a high quality entropy source to generate a keypair. This
498+can block automated tests and is difficult to turn off. Therefore for
499+test purposes it's easier to keep a generated keypair in the source
500+tree. This also saves resigning test input files on every test
501+invocation.
502+
503+privkey.asc and pubkey.asc and attacker-{priv,pub}key.asc are test
504+keypairs checked in to this source tree that have been generated for
505+this purpose. They should not be used for any production purpose as, by
506+having checked it into the source tree and published it, the private key
507+is now publicly known.
508+
509+To create replacement keys, set GNUPGHOME to a temporary directory and run gpg
510+--full-gen-key. Then export using "gpg --export-secret-key --armor >
511+privkey.asc" and "gpg --export --armor > pubkey.asc".
512+
513+Delete everything in the temporary directory and repeat for
514+attacker-privkey.asc and attacker-pubkey.asc. This keypair is used to
515+verify that repositories signed by somebody else are correctly rejected.
516+
517+You'll also need to re-sign the individual Release.gpg and InRelease
518+files under this directory that are signed with this key. Use "gpg --yes
519+-o Release.gpg -ab Release" and "gpg -o InRelease --clearsign Release" for
520+that.
521diff --git a/gitubuntu/apt_repo_test/attacker-privkey.asc b/gitubuntu/apt_repo_test/attacker-privkey.asc
522new file mode 100644
523index 0000000..a47202c
524--- /dev/null
525+++ b/gitubuntu/apt_repo_test/attacker-privkey.asc
526@@ -0,0 +1,105 @@
527+-----BEGIN PGP PRIVATE KEY BLOCK-----
528+
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
630+=tGsK
631+-----END PGP PRIVATE KEY BLOCK-----
632diff --git a/gitubuntu/apt_repo_test/attacker-pubkey.asc b/gitubuntu/apt_repo_test/attacker-pubkey.asc
633new file mode 100644
634index 0000000..aee77e1
635--- /dev/null
636+++ b/gitubuntu/apt_repo_test/attacker-pubkey.asc
637@@ -0,0 +1,52 @@
638+-----BEGIN PGP PUBLIC KEY BLOCK-----
639+
640+mQINBFqOsp8BEADUmBAMxDfLmpCAUv2WU+ozJ0I9IHh/nPmSKlIVYk7OklognJvk
641+OkABlEnZucXzmzHWYla45wOn3RvCgOMZOVApRIGcI3Do+4zesK83Zz2ijNwyS//P
642+do1TTlDiedRvE7rNAIJ4DwebH7Lx5UP5avgymK7JGX9+WFpAJtONdL1rruMpi/5O
643+UU1dUxWN8Z3etdgmcI3rMwUAdWPX3RHWwEN6OTNySc30Tiujt4+n9UNBwFHzzMij
644+yJSRxyBT31nMFs/7qyxLQCIjUBg2g+o/EXyJv4a5bNz678qcvsAVYcP4EvUUMD1W
645+Srl0hSBAuLrFJeyzSt9YkmDp4qJpYLUsnitgWX7XCZ/wmcevBHRAbqFMWo8BS/jy
646+xHf3ZD02uwKukivwM74PmeNC9ZWb2dXM/BcTMKUn2SyJv5uoIyFTxJfGKE6gWvap
647+CAaCpL6wQZVqNLKLapgVFbGevXhZSOBZ2EIhAWrrxwftoku4WZO1UD4A6Zb52dzi
648+TA8P5OB/hCK2oa5DI4cM1gWgybYeUE+EysTrGFZMUmLyd2PmsprUQQ71AARZFQIi
649+qM1s9Tm3oWQEynVdLehUYKTNhGV2XqKCRQZc51C+qR4N9lzdZQ76TuMI+PWjB5iC
650+eFMOZSCRiDyuEOdHnoYDZoK8mB59l+FpgS32fnz9mjCq74mcyxibiDDY2QARAQAB
651+tFZnaXQtdWJ1bnR1IHRlc3QgYXR0YWNrZXIga2V5IChwcml2YXRlIGtleSBwdWJs
652+aWNseSBhdmFpbGFibGUpIDxnaXQtdWJ1bnR1QGV4YW1wbGUuY29tPokCNwQTAQgA
653+IQUCWo6ynwIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRCZQ2oehdgm+UKO
654+EADQLlBm8T67zc6RokwEr6zYrC7WJZ1Ei//X2dx8vOTpIJZY+TPV05L34s20xUoX
655+4P/2GIsoCO17Gx0Igk2w8t65AlpIbp03dMOs52EhY9klqXfpxCyo+TDbafCNczIw
656+yZdfVFRZRoYGqhI+uwFpVjqC0Z6ltjYQ0gPR97R4jvjLSKxdqKsMp92Lr5Tnv0Tg
657+ubptYy5ijOUguzFutth7khXRdF2c94F1wodevQ84DtRaxyvR26NPC2GTvf8mIXwp
658+A5wazv0Bj8+UICW2oriTE3SCC8e68RxDcSSOprdmQMdbx8LatIfQbXEWMkepCHQS
659+P5Nh6zYD62ik8meiLIrCzQLRZVRLVtpQz2Udd+8e8RqncPDMNdTNqq/xmkAqFJ/i
660+XMvF0Q1U/aB6fqiaae2iJFm93Eof0YYhEKvY45taY8nl5GOUQw9OUdURx26+lylk
661+aVOq7QJjhIldGFX2AtmZaGdEZsjjVJ4PJOkee58+svmssVkgnM1uh0OI1TlxtmHb
662+0qNLwbw/UukCO8NNU/pCMQZQOJycBlArvk0GNet6xO5PdEboLZY4t95zkdu90z6t
663+TMzGjXziCxphyvfo22Zk4ajz05dBV2GXz3MYQysE3zXsckYoJzWk2DUXZOmJ18Dz
664+aIBnxxUypY3PMnZ5LvUxWRmEkEvgswMeyvUV4elVZBplDbkCDQRajrKfARAAvAIA
665+5NzHJ3AjqhByiqT7mwsrsX7HWg1EuiCB+P5mnVyakY/QzQnpRRBT1BSr7Ipxip9m
666+anhEDgPMqN/SyzVpjGBHYypWMEFLkTUozg50WwpYPwKAX+LZkF+XqESCx7Zx2Q/c
667+JpdCmgC3pjcBIT7NEXCiRZLEkvBwqMl74xgo0u+Z7zuFgUCPdd5NPGlzxyE0hFUS
668+tXIz6kZlBdzXGE3eGEKmo4CmtE9CoUlQ1dczTFUJ49jmBNzag/9v2P6q5flDdibr
669+XTYZdUgz+5AhZK7Nmrsx4DA6bc2KJFetCQT1O2F4/p7eIxlHj9eJz2rY6/aTZ7M7
670+RGLNltmlUKdxD5tqzCNnVOFic5Ofh3K7Tddm+cHDnbj+gY5O1DNg4XOfKnPJoJQM
671+34m6tR6DO+dr5/Z4TIcOMSKKwcZUvf8rk10MMssYgXpszVjoRuJS4zeQd71Mc8EX
672+rahfocpPtE3tkCM0jOGSFelBGrfLcZFDVijZmiqizwN6HJqnKcxJGg/+hb4kgb9i
673+VpjMGi21zKTOUXArfkZkW6l5/85iLZ0+pRfToPv4mtQx7Stu+dilDZ6cQ8d1y887
674+Eb9BZeXpJ14mRUA5mSYEe1jGXYYSlcevwzh7PwHX9OLsCajXZrlLQfLpQZdnRoIo
675+S6uYXMl4KoS3ZOz24Js/KOkmtwlcCm+65jJdfRsAEQEAAYkCHwQYAQgACQUCWo6y
676+nwIbDAAKCRCZQ2oehdgm+YvEEACQnOs8OnZxOuZNVWSbO/Z5Rn1zMB6jYnmfZEnk
677+XnX9vbfW34lw5u42e9X4w2+Fw4Oz7Qh3teE3XsieexOnNEmCnGIl/4d215ioHawq
678+uja3DIRa8K7IjpXGY/uPhENQV5J04KiB+JuD/zRJzSiD4Vbnmv8kNvRk5b0MYVLy
679+CDwg2adbBv6qI6f2isgsKXRGdOyKg0ANxcj/4PfRrGMPuXmUwrNHC0vet3GjVlaS
680+SGhUV0bPUcdw2h26VXk3hJVPo1WlqPY+i28+IGlqqJreC60WQDB9sCDI7l/jp4+Y
681+OogmnR+y/8CGBNjyy9eRs3BQQdHrJO8ykrv/Jx6odEmN1zlm0ADbPHjWCbq7Ue3m
682+SRBA0qQay7quk+XUy1bij+/kmgnYj3jvdVukhhshD6hnAnwTyxfOGDqzO3XFFVdJ
683+T+07REzTrvEShLIE4xOeyo1XW9TS2MDBWGQWO+2Q9yFcdmEYCn6WQlFCr5ZSSRw1
684+E+rumkfOn8jo1QDMS4T7LKFAKnfYb0Z7z+RsOaH7Qg6ByxBMaw9DtkwciCDNYvyq
685+IWDQgWBGTFiT5b6jr468NO3oDz6uzwGYEFvIBE+aT+PPUcsP3ffuTksipw430A4r
686+vaz4NZCwB521If27LM6C/V9YDksDhkY29iXIOZ4MFnGEE4FXMERkMH352pZSvmMH
687+QBHMEg==
688+=uXoS
689+-----END PGP PUBLIC KEY BLOCK-----
690diff --git a/gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/InRelease b/gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/InRelease
691new file mode 100644
692index 0000000..e6e4fd2
693--- /dev/null
694+++ b/gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/InRelease
695@@ -0,0 +1,38 @@
696+-----BEGIN PGP SIGNED MESSAGE-----
697+Hash: SHA1
698+
699+Date: Thu, 22 Feb 2018 12:54:31 UTC
700+MD5Sum:
701+ 4f48c54612fd07809b30057a9d276b03 36 Release
702+ b953e2f94716ed61d0e20ce4199e882d 17 main/binary-amd64/Packages
703+ efcc6e6d5e421f11a17c47c61b5918a8 16 main/source/Sources
704+SHA1:
705+ 6129e87be122547e3c1d8c92790bc77cba262812 36 Release
706+ 17e117e61288adacc2a68bd92cd53ee4ce6d0075 17 main/binary-amd64/Packages
707+ 29ecd6b099df45721dbf0169d574fd7cf0b77fb1 16 main/source/Sources
708+SHA256:
709+ 43892aeed88dde99f15204d74a8379595a1548b919d2f5389cc9c840a9d93366 36 Release
710+ 356d78da143459ff58ab3232348a9d318b728fd2a25d964a61f4af21f7012209 17 main/binary-amd64/Packages
711+ 106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 16 main/source/Sources
712+SHA512:
713+ 04c3324cd464cab05b349c3d6b6ce08b7d7cf70e343b16cf03805220ca1e8ec3b2c084a906b06033bf917a611e1f309590d9c2f19c668cb06b87abdf641ec000 36 Release
714+ d6b5e77247e78c60e2e277bfc5b32ac46090b28ac530c1a59e0fb1432025525b9643a2d3648fc6bc583a7ce62c8c3c0781a92d0ef9356bf71edbe887c7a922c8 17 main/binary-amd64/Packages
715+ f62f22397280f07185a0f12122b7c757596a8b9fc34b798aad877ea27a96919ed14ca64bbedeea8f21baf44472e7c1fad398866e5ef41b79d89508da0d3180d6 16 main/source/Sources
716+Acquire-By-Hash: yes
717+-----BEGIN PGP SIGNATURE-----
718+Version: GnuPG v1
719+
720+iQIcBAEBAgAGBQJajsGJAAoJEN8hzJEp/3jmzIkP/1fEdqVSfO1TySL+O8S6JbRD
721+L3XlnOheGCL/eZafYtLf9uWkDt+43iXVeUrSQVcTuE6R7rBYxFVP/J03/AAq3LYP
722+rqL0v43Qj/8XbG75FrepOP2BJWeZcPHQv5xe4ykPb1GaGJHbV8x2z0lFlhhv8z9C
723+//1W+SRch/UPOMhCO+CYIcQr1iatjxZa0qK6CS7OR566h8Fw3tN0/YNUZ36XvQwG
724+EcWUc7bim/7NZ3fBDZpbnb91VZO2Sft0vZOyd9Qg8AmxjCizaj+UQJdKFtiVkdhK
725+vPMWSnt2kdCbpL5RX3yqx9g6+BRtIUhjEGnym0s9W+NIn9LkSaxHK8ol40VfDXLe
726+x79ts3chBymAjqDecpQdf3NAg3vNHVL2ZNkuXZJwGjEcFfAoiDsbkVNC6qyAwC3C
727+FRTGgdMrduCdaHkRZcIR2VRNsLUHm36x7PS9zz+B0m0GsD+u2BF7LmHqXF6UQ6XZ
728+X2U+ccvfUUUOaW+pXUPGX8B+FQYAZ7TsHDPNO/GqWUIsesF7wxmjnbBGLK4fluWA
729+86UaNrehmTGIzeTSXIj/QYma9HgSJ0gYM4gu+1rB8Na0V9QG/n+KyD3Ummec3cI+
730+fzdy0D2LoYn4yNoWjMpze1nDSfhAw87qur5ITryQfMHj1UsImcZy6db23cD5wdAX
731+F/gb/uPFGzHkjLPpJEGn
732+=pY/3
733+-----END PGP SIGNATURE-----
734diff --git a/gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 b/gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1
735new file mode 100644
736index 0000000..f46f8f6
737--- /dev/null
738+++ b/gitubuntu/apt_repo_test/by-hash.badfile/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1
739@@ -0,0 +1 @@
740+sources-content-corrupted
741diff --git a/gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release b/gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release
742new file mode 100644
743index 0000000..c67ce17
744--- /dev/null
745+++ b/gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release
746@@ -0,0 +1,2 @@
747+This file is signed by an attacker and this should be detected before it is
748+attempted to be parsed.
749diff --git a/gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release.gpg b/gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release.gpg
750new file mode 100644
751index 0000000..16eab00
752--- /dev/null
753+++ b/gitubuntu/apt_repo_test/detached.attackersig/dists/bionic/Release.gpg
754@@ -0,0 +1,16 @@
755+-----BEGIN PGP SIGNATURE-----
756+
757+iQIcBAABCAAGBQJakCpRAAoJEJlDah6F2Cb5GxgP/0DAzx5bx/4ApuQZUB2nzRh+
758+6pYm7y2ceFGPymtKXiNeuQQFmc2zfyR4cmSNovhk/w6wz1duwK7weQTINXiILPOA
759+CVLKfYOjB5fHi6Fx6ZBBuS87H4dU/R3Y0o79AUtmiimoFv71PBqxYNTN+cwiLH3D
760+Wm2QjTXWY7FA6+I/qTXP69H5WdniUDRF8hRVmNNEMws29Jk5tPz1zIGgpL/S2lZn
761+8yanojtscaCvwp9TGLysIDwRoO0i46NxlUwHyj1VRhXPZystDXkXSDJnMEECY3ps
762+ypaxsorzRoE0r1gLhbyYpu0ZVacNQ36XhKi+36YF4qvEQCVhL/+sJZ6UpFjTbUby
763+5bC+2NlwgMepr8iE8Ov8flxeLQx/OD841jy6FbUrLu2K4nLn2JD0XlMMPYjFJeFy
764+SZ3nCeaCD0GZdwRslv4DXL/aK9z2JX4daA9ChMIyXSJzZr7OWTqDo11qlIScgD2B
765+QmEvUMZ0dCkVCrCuNEbTlybRn2GVgRfp/VaTmr+H5ro8AAFsJm6syKSlM2ITFliS
766+RpkuWJa8YphJNUMpPujhzyCZ9K4mlqqZMCj2c4Nx4FP1+5RvjliZSqga93B+IXOP
767+XB1T3sHs6AEvTtHnwemBoP/IaLcgH5lFsgL/aLCkWULvOnxDn5lhxb4FM/I085zP
768+Kcxv/DKHKKn8Ztep7DZg
769+=ADvg
770+-----END PGP SIGNATURE-----
771diff --git a/gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release b/gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release
772new file mode 100644
773index 0000000..d880aa7
774--- /dev/null
775+++ b/gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release
776@@ -0,0 +1,2 @@
777+This file is signed legitimately but has a bad signature and so this should be
778+detected before it is attempted to be parsed.
779diff --git a/gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release.gpg b/gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release.gpg
780new file mode 100644
781index 0000000..f49bc19
782--- /dev/null
783+++ b/gitubuntu/apt_repo_test/detached.badsig/dists/bionic/Release.gpg
784@@ -0,0 +1,16 @@
785+-----BEGIN PGP SIGNATURE-----
786+
787+iQIcBAABCAAGBQJakCn3AAoJEN8hzJEp/3jmOO8P/1xfyqPmptW/vG5CUgKhsJNZ
788+FEmueYsU4Za0NwfJmY5KeXBJqhfjkmgBtEbGfcV6XIBUoolmrg3qnTTLqnnhjH0/
789+HrSLKAGVxDllGssIpYrPvth7jgn1A7NAiyE8RAuEi9nybFXb8o71k3HoMaqFWEIc
790+NGyhvhVSL31J3CahrGKhXftNMfQr9FGYe7JaX5tpzUn4qWzH3xfkZER6Zya/BYRH
791+Gzoi5VW3c7drGGaS5ffsbcF+5soTOko1FsanOgqGQHPsesta0b/tNNzW6wVv1NNf
792+SmLYOvoM92niJcJSf0AWcFz1zroSuXTrOlMlpU+pdUDde740cTEKzgJkhSSB5eHm
793+EA2fDvDEiO2io/jazhIWrWd8+fNC3WrCHJCPVbTQybwb89XHRstwROA18Z0fMq2o
794+d2o4C+KKUHedSjf0pKwWVrr0I9mpMeDVlgsKqo8XSRNTpGzL3KUCjzGJX0cFgbUU
795+1MXYjW0isPUDfdk0FeiYABIStYcGi6akCwWIKClVFBx6CseXAwJzQUAJF8JneNzy
796+RfT0enAraY48gSQBpqjXyPIopbgAhgJmbBQ0jo/JLqmw7Py/SJBP9KZCGNMdjzOF
797+aklhZoEf1xqKb/uqvCHta2RqlQzXLK6dDsjQcC/T3Z7IjUvm0/DsQA9SJsZAgqhP
798+OdBZKAySj4SvvrpnA3xW
799+=0OBM
800+-----END PGP SIGNATURE-----
801diff --git a/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release b/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release
802new file mode 100644
803index 0000000..04d0f3c
804--- /dev/null
805+++ b/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release
806@@ -0,0 +1,18 @@
807+Date: Thu, 22 Feb 2018 12:54:31 UTC
808+MD5Sum:
809+ 4f48c54612fd07809b30057a9d276b03 36 Release
810+ b953e2f94716ed61d0e20ce4199e882d 17 main/binary-amd64/Packages
811+ efcc6e6d5e421f11a17c47c61b5918a8 16 main/source/Sources
812+SHA1:
813+ 6129e87be122547e3c1d8c92790bc77cba262812 36 Release
814+ 17e117e61288adacc2a68bd92cd53ee4ce6d0075 17 main/binary-amd64/Packages
815+ 29ecd6b099df45721dbf0169d574fd7cf0b77fb1 16 main/source/Sources
816+SHA256:
817+ 43892aeed88dde99f15204d74a8379595a1548b919d2f5389cc9c840a9d93366 36 Release
818+ 356d78da143459ff58ab3232348a9d318b728fd2a25d964a61f4af21f7012209 17 main/binary-amd64/Packages
819+ 106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 16 main/source/Sources
820+SHA512:
821+ 04c3324cd464cab05b349c3d6b6ce08b7d7cf70e343b16cf03805220ca1e8ec3b2c084a906b06033bf917a611e1f309590d9c2f19c668cb06b87abdf641ec000 36 Release
822+ d6b5e77247e78c60e2e277bfc5b32ac46090b28ac530c1a59e0fb1432025525b9643a2d3648fc6bc583a7ce62c8c3c0781a92d0ef9356bf71edbe887c7a922c8 17 main/binary-amd64/Packages
823+ f62f22397280f07185a0f12122b7c757596a8b9fc34b798aad877ea27a96919ed14ca64bbedeea8f21baf44472e7c1fad398866e5ef41b79d89508da0d3180d6 16 main/source/Sources
824+Acquire-By-Hash: yes
825diff --git a/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release.gpg b/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release.gpg
826new file mode 100644
827index 0000000..c5789c8
828--- /dev/null
829+++ b/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/Release.gpg
830@@ -0,0 +1,16 @@
831+-----BEGIN PGP SIGNATURE-----
832+
833+iQIcBAABCAAGBQJakDbbAAoJEN8hzJEp/3jmZKIQAJvyvvUwcJEG6PIgU0lYrK42
834+4cAfSuSnsJg//eq+VTMi2qMMWzyEkcpkRV7Yhy3EMAgSmTsvdqJth5ptPq4Mpwcq
835+Hn9hP/y/IEfoAc3f/gFdZ/RjDxhjFikJ0F9QwKNoAiurWpr1xyIma7cWlI70YrQI
836+kjTfzJ96N9l2Z5hfMQFmjXKlh80cXW6w/yyAcdQPu7veeidRN2GdK0u9NrcPjNrJ
837+UvMtdXMsuoeQzVhbEja9npbTwNSf7Q9Ap/NZXv9rgc2Mn41rvuw+aDo1cBpt0QiZ
838+z67pXWIVfLLy9qoygti2CoAEccU/IODzGCJIhzTPRIU0XkrXvw2k5Q8GtUgAwbWn
839+FxV9WR4FKo2N8yHiH+4MEmq1zL4G8o9vK36URoKsE57gx/bX/3XEKN0Qp8+/gyri
840+7SuC5flCgG9TVbTpByzl6I+ikDXYb2rVGMpaj255gsMGHzfb54uJeo7VXvr8jy4j
841+DBnHySJ0l4uwMxahBxNkxKk/KBTQ7RFwK/cT908OutXSM6AgXnlwxEW6QPKZcwaV
842+dAJZtJns076Eb+6UL9wrlP2Ciy0ODwlxnFsMnQlB0L0gJlHwIpOPcVRljALTNjdf
843+fvcnpUsAiBLIuqbbZ6Z6y4O7OQiNb8kV1idOKYFO4RNrO9/FBxlC5qREZPWEMSqk
844+BPOjpKz3A33+GO+x6c0Q
845+=KfnX
846+-----END PGP SIGNATURE-----
847diff --git a/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 b/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1
848new file mode 100644
849index 0000000..04efb3f
850--- /dev/null
851+++ b/gitubuntu/apt_repo_test/detached.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1
852@@ -0,0 +1 @@
853+sources-content
854diff --git a/gitubuntu/apt_repo_test/inline.attackersig/dists/bionic/InRelease b/gitubuntu/apt_repo_test/inline.attackersig/dists/bionic/InRelease
855new file mode 100644
856index 0000000..d2ab1b3
857--- /dev/null
858+++ b/gitubuntu/apt_repo_test/inline.attackersig/dists/bionic/InRelease
859@@ -0,0 +1,21 @@
860+-----BEGIN PGP SIGNED MESSAGE-----
861+Hash: SHA256
862+
863+This file is signed by an attacker and this should be detected before it is
864+attempted to be parsed.
865+-----BEGIN PGP SIGNATURE-----
866+
867+iQIcBAEBCAAGBQJakCMwAAoJEJlDah6F2Cb5Ge4P/RAIRPYmOhS9I1w3g4F53Y2y
868+odmaXqjDG8Gam9h2ez6e3vkFUE0OUogE9Ng5o+RW7NP4cQ21Oei0KHExVCFCCHxY
869+6tjw5eCvVzxiWKkvTqr1IidvafSKZpVCPxDPSUCpoSMHiPD2zes6rX2BENJr13pY
870+7JCIlBfX+ZOqUgI7jGWEmPdBf3oQzRuJO2Nltty0eRv1eMbzoZu2eOsrbhy1N1I+
871+kfrc+VSvaZmIGhtwWI3pkdW2XbXSzBryle+esofCde3dW6YReQcE8A48X+6PWt29
872+U0kHSLYHntu4rJ4Jwk0r6EGKtjcTj9fpOO2K0/KnlnYzKk0lnFDxIstITmcnFz9j
873+rf0ShXMfLeuoT9F9LCZKCl4178ZcBqjEFAzVjEKGN4QvQf9RM7cHHz+A2++Iu5al
874+JiznirUkuR3Ifz+WSRHU9rZV9voV3PSQDJbRvqmZhMFmMSRp50dRpoDcQP9BS2V5
875+m8ysVDxNIqn1u8Hkb2Mm8tJ4P3/ITM+slJpKPFQG7nOWmFtZ1AoKEemx3xRiAvRr
876+PabXk7+1HrX2oOwlRSxq2cRpLfujfTqy7UFj7Qu2gRlqnAKMVhlo/EIQ7knFFMge
877+Gqb13eDHit6f70g4+cTscRFM0XnqLpghiSFZ+cn/0ZttWipYpsNzjwbl+YvTndpb
878+3x/kZz2pCtlgrYzzGtJF
879+=PZMr
880+-----END PGP SIGNATURE-----
881diff --git a/gitubuntu/apt_repo_test/inline.badsig/dists/bionic/InRelease b/gitubuntu/apt_repo_test/inline.badsig/dists/bionic/InRelease
882new file mode 100644
883index 0000000..8040a1c
884--- /dev/null
885+++ b/gitubuntu/apt_repo_test/inline.badsig/dists/bionic/InRelease
886@@ -0,0 +1,21 @@
887+-----BEGIN PGP SIGNED MESSAGE-----
888+Hash: SHA256
889+
890+This file is signed legitimately but has a bad signature and so this should be
891+detected before it is attempted to be parsed.
892+-----BEGIN PGP SIGNATURE-----
893+
894+iQIcBAEBCAAGBQJakCPHAAoJEN8hzJEp/3jmnpUP/35GamMSl7n50xDAvUtGjVEw
895+RUaMWvaeAVdAxLiWHaAjY7PyknniI38GCjNDKTByCLaXB4wcWb+N7KvRDqWUmfZR
896+on+mxwGlbHS9DULd+wPjDVFvATrG/oYE9Jr+eKf5TGZfxkfg4kMICEEitO9TGqxK
897+esx8hN2ZA+9ktzraAe3Z2DBHFizym47tbXCSRhS2QEvmJxf/qhhGW546WjvwW6Vr
898+C7wTG3BVa2NH7nA/QaIfERbRcUXCiMC1kqayOcypLQLqjttcERB31BnFhd12TMsM
899+VLZucbk9kHoujhfrzc5hKA16znGK8qPIeKwYt572kKLn/VrqfaWhgVZebzN/FPhj
900+CHyWsRL3Wxfp5BaRRe8w3gOEnjCCAKoEVjF58uwf4lVCqzfArX9n+tJhi843prqY
901+6cKcxlDkVuZDOiv/567QAIAPubjIxjYlqZMWGdZecGzNKGEr3hZDmztjg2m4jGGZ
902+m1HiDXJgYQVjxKg9SFlk2OFYpC+ivseWQeGmiNI/TPFtvTJMMP5d5MK+iltdWjnB
903+YTXrg6JFEQGsbDSzecA6gpNuU5Taint5XsalmBFyBpXmCYihHWI/l5oipOhYSRGt
904+qWdAHPloCMq9jpQFAYPxuYJNsWF5OrOXydJm68u/D8PL8SZ/cgGvszEBSJyHzbdJ
905+wF4JCVMJB3Hdx4NI3yNh
906+=sA9W
907+-----END PGP SIGNATURE-----
908diff --git a/gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/InRelease b/gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/InRelease
909new file mode 100644
910index 0000000..e6e4fd2
911--- /dev/null
912+++ b/gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/InRelease
913@@ -0,0 +1,38 @@
914+-----BEGIN PGP SIGNED MESSAGE-----
915+Hash: SHA1
916+
917+Date: Thu, 22 Feb 2018 12:54:31 UTC
918+MD5Sum:
919+ 4f48c54612fd07809b30057a9d276b03 36 Release
920+ b953e2f94716ed61d0e20ce4199e882d 17 main/binary-amd64/Packages
921+ efcc6e6d5e421f11a17c47c61b5918a8 16 main/source/Sources
922+SHA1:
923+ 6129e87be122547e3c1d8c92790bc77cba262812 36 Release
924+ 17e117e61288adacc2a68bd92cd53ee4ce6d0075 17 main/binary-amd64/Packages
925+ 29ecd6b099df45721dbf0169d574fd7cf0b77fb1 16 main/source/Sources
926+SHA256:
927+ 43892aeed88dde99f15204d74a8379595a1548b919d2f5389cc9c840a9d93366 36 Release
928+ 356d78da143459ff58ab3232348a9d318b728fd2a25d964a61f4af21f7012209 17 main/binary-amd64/Packages
929+ 106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 16 main/source/Sources
930+SHA512:
931+ 04c3324cd464cab05b349c3d6b6ce08b7d7cf70e343b16cf03805220ca1e8ec3b2c084a906b06033bf917a611e1f309590d9c2f19c668cb06b87abdf641ec000 36 Release
932+ d6b5e77247e78c60e2e277bfc5b32ac46090b28ac530c1a59e0fb1432025525b9643a2d3648fc6bc583a7ce62c8c3c0781a92d0ef9356bf71edbe887c7a922c8 17 main/binary-amd64/Packages
933+ f62f22397280f07185a0f12122b7c757596a8b9fc34b798aad877ea27a96919ed14ca64bbedeea8f21baf44472e7c1fad398866e5ef41b79d89508da0d3180d6 16 main/source/Sources
934+Acquire-By-Hash: yes
935+-----BEGIN PGP SIGNATURE-----
936+Version: GnuPG v1
937+
938+iQIcBAEBAgAGBQJajsGJAAoJEN8hzJEp/3jmzIkP/1fEdqVSfO1TySL+O8S6JbRD
939+L3XlnOheGCL/eZafYtLf9uWkDt+43iXVeUrSQVcTuE6R7rBYxFVP/J03/AAq3LYP
940+rqL0v43Qj/8XbG75FrepOP2BJWeZcPHQv5xe4ykPb1GaGJHbV8x2z0lFlhhv8z9C
941+//1W+SRch/UPOMhCO+CYIcQr1iatjxZa0qK6CS7OR566h8Fw3tN0/YNUZ36XvQwG
942+EcWUc7bim/7NZ3fBDZpbnb91VZO2Sft0vZOyd9Qg8AmxjCizaj+UQJdKFtiVkdhK
943+vPMWSnt2kdCbpL5RX3yqx9g6+BRtIUhjEGnym0s9W+NIn9LkSaxHK8ol40VfDXLe
944+x79ts3chBymAjqDecpQdf3NAg3vNHVL2ZNkuXZJwGjEcFfAoiDsbkVNC6qyAwC3C
945+FRTGgdMrduCdaHkRZcIR2VRNsLUHm36x7PS9zz+B0m0GsD+u2BF7LmHqXF6UQ6XZ
946+X2U+ccvfUUUOaW+pXUPGX8B+FQYAZ7TsHDPNO/GqWUIsesF7wxmjnbBGLK4fluWA
947+86UaNrehmTGIzeTSXIj/QYma9HgSJ0gYM4gu+1rB8Na0V9QG/n+KyD3Ummec3cI+
948+fzdy0D2LoYn4yNoWjMpze1nDSfhAw87qur5ITryQfMHj1UsImcZy6db23cD5wdAX
949+F/gb/uPFGzHkjLPpJEGn
950+=pY/3
951+-----END PGP SIGNATURE-----
952diff --git a/gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 b/gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1
953new file mode 100644
954index 0000000..04efb3f
955--- /dev/null
956+++ b/gitubuntu/apt_repo_test/inline.by-hash/dists/bionic/main/source/by-hash/SHA256/106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1
957@@ -0,0 +1 @@
958+sources-content
959diff --git a/gitubuntu/apt_repo_test/inline.injection/dists/bionic/InRelease b/gitubuntu/apt_repo_test/inline.injection/dists/bionic/InRelease
960new file mode 100644
961index 0000000..f15ae3e
962--- /dev/null
963+++ b/gitubuntu/apt_repo_test/inline.injection/dists/bionic/InRelease
964@@ -0,0 +1,37 @@
965+Injected: yes
966+-----BEGIN PGP SIGNED MESSAGE-----
967+Hash: SHA512
968+
969+Date: Thu, 22 Feb 2018 12:54:31 UTC
970+MD5Sum:
971+ 4f48c54612fd07809b30057a9d276b03 36 Release
972+ b953e2f94716ed61d0e20ce4199e882d 17 main/binary-amd64/Packages
973+ efcc6e6d5e421f11a17c47c61b5918a8 16 main/source/Sources
974+SHA1:
975+ 6129e87be122547e3c1d8c92790bc77cba262812 36 Release
976+ 17e117e61288adacc2a68bd92cd53ee4ce6d0075 17 main/binary-amd64/Packages
977+ 29ecd6b099df45721dbf0169d574fd7cf0b77fb1 16 main/source/Sources
978+SHA256:
979+ 43892aeed88dde99f15204d74a8379595a1548b919d2f5389cc9c840a9d93366 36 Release
980+ 356d78da143459ff58ab3232348a9d318b728fd2a25d964a61f4af21f7012209 17 main/binary-amd64/Packages
981+ 106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 16 main/source/Sources
982+SHA512:
983+ 04c3324cd464cab05b349c3d6b6ce08b7d7cf70e343b16cf03805220ca1e8ec3b2c084a906b06033bf917a611e1f309590d9c2f19c668cb06b87abdf641ec000 36 Release
984+ d6b5e77247e78c60e2e277bfc5b32ac46090b28ac530c1a59e0fb1432025525b9643a2d3648fc6bc583a7ce62c8c3c0781a92d0ef9356bf71edbe887c7a922c8 17 main/binary-amd64/Packages
985+ f62f22397280f07185a0f12122b7c757596a8b9fc34b798aad877ea27a96919ed14ca64bbedeea8f21baf44472e7c1fad398866e5ef41b79d89508da0d3180d6 16 main/source/Sources
986+-----BEGIN PGP SIGNATURE-----
987+
988+iQIzBAEBCgAdFiEERWDUrwcfVETLrYJ63yHMkSn/eOYFAlqVQHkACgkQ3yHMkSn/
989+eOb2ow//fx68CRU2GYMwMaBNZP/S8a/2jfr+zMA403hmmx63Mw/0t8w8dHBQrmxl
990+MgmDtcyJvsqdF/zi1cWJzyPFK+0xrMPP6U+jNw07eOg5+IF+l3GlzPQuf0BMaxPZ
991+DtjWL8Nwu9FeSfcFv9xrk8Bg7LbnFWLh1hmKmPQUnDju/vTVV1XI4cEK2mxVxhm1
992+UiUsOyGXY7tJJyP3sJVCHSMpWzJfmBGHjwgcHRqTA1s341ticw1J3OCUnYaMya8O
993+HZ+zgqsPRZGD+VD/3On/5OoJdzBblVlVd2YMfdQuFq6H4xvxWMntGkQ4f3zP2jt0
994+3/GVLc2cUqbSKkkhbbKP82rj2xdLW+Y4p2u/9TxLL7YoM2qBq49L8Hw2WjbSaN62
995+955pOQZ7UIKr9b1K7lppt4nQW3Irt4wC5zxl8ibPT/FGxxPmSbhLq4M5TQZEX3vi
996+zLrtMl8ffgqO/qnT/ieQJW0g0KM9STHqdDFwYNiSY4EP3L0mI4EnmK4FxiwD4hKu
997+Lge3L8vLFgokiXAswy0c79MaElLKJRQ9yn7hKTl9sdrTsaqtl6cetKufjhlcmOFz
998+XF2397WNPisnOkzd/CIb7O/mVO38/HQD7xtj4ONeoYMrH/UAtCp4dwpFcFTP9Lb6
999+w4PagHdUC7R9mYaHcrjMA75RoDo/MoULmqAoemiQEgbZQ6yY2zQ=
1000+=gQ3h
1001+-----END PGP SIGNATURE-----
1002diff --git a/gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/InRelease b/gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/InRelease
1003new file mode 100644
1004index 0000000..5f4a268
1005--- /dev/null
1006+++ b/gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/InRelease
1007@@ -0,0 +1,37 @@
1008+-----BEGIN PGP SIGNED MESSAGE-----
1009+Hash: SHA1
1010+
1011+Date: Thu, 22 Feb 2018 12:54:31 UTC
1012+MD5Sum:
1013+ 4f48c54612fd07809b30057a9d276b03 36 Release
1014+ b953e2f94716ed61d0e20ce4199e882d 17 main/binary-amd64/Packages
1015+ efcc6e6d5e421f11a17c47c61b5918a8 16 main/source/Sources
1016+SHA1:
1017+ 6129e87be122547e3c1d8c92790bc77cba262812 36 Release
1018+ 17e117e61288adacc2a68bd92cd53ee4ce6d0075 17 main/binary-amd64/Packages
1019+ 29ecd6b099df45721dbf0169d574fd7cf0b77fb1 16 main/source/Sources
1020+SHA256:
1021+ 43892aeed88dde99f15204d74a8379595a1548b919d2f5389cc9c840a9d93366 36 Release
1022+ 356d78da143459ff58ab3232348a9d318b728fd2a25d964a61f4af21f7012209 17 main/binary-amd64/Packages
1023+ 106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 16 main/source/Sources
1024+SHA512:
1025+ 04c3324cd464cab05b349c3d6b6ce08b7d7cf70e343b16cf03805220ca1e8ec3b2c084a906b06033bf917a611e1f309590d9c2f19c668cb06b87abdf641ec000 36 Release
1026+ d6b5e77247e78c60e2e277bfc5b32ac46090b28ac530c1a59e0fb1432025525b9643a2d3648fc6bc583a7ce62c8c3c0781a92d0ef9356bf71edbe887c7a922c8 17 main/binary-amd64/Packages
1027+ f62f22397280f07185a0f12122b7c757596a8b9fc34b798aad877ea27a96919ed14ca64bbedeea8f21baf44472e7c1fad398866e5ef41b79d89508da0d3180d6 16 main/source/Sources
1028+-----BEGIN PGP SIGNATURE-----
1029+Version: GnuPG v1
1030+
1031+iQIcBAEBAgAGBQJajtw6AAoJEN8hzJEp/3jmxO0P/26hJvKfSPuiCLcJw3sH4FxS
1032+N26duNo1/Afx/nFrQLkX27hIby9YlZcbqkFkoBYcvHzrCsWmRbdjYtOPXaP9B58Y
1033+XNq+jECTYfl6bVPiwwSMO3m365+1V5P6OxM+YuyU6W1IXDAI2rQUn7tyUK0DN1iW
1034+wSknkkAajZm+dAbTD20bkR+kWfK6ZM1U24zJF6WRKB/VGyykioy35ZUUpxwxOG5T
1035+Mx538CDS+cReGTBPfhN6863RSwIaDOS7DzsUXu2ac+9QQ3HvejCzgRK8Q10xDg4p
1036+21i2YiHStJYLz2/Ai4jbZa58rAHG1e8QNNv7gZN2fgTcD30FvZNbHzrPgiXjHCVv
1037+Q+rD8VxSjZwgWJOBPZ3zJMx5UqNKPay2Qs1Bd78pfkESDftoYCxayzJ1zWJaCNdC
1038+vjRlQxqMO5HRha1kE4fM1pEl4rHzt3Byfd0hnW1g/bgkiM08jooId+U9JTtt5aon
1039+zY0f/gKq6Gz5mCZ5RMmVq7cO4FY/gMlaoJ2LfnvtkFI6sBOKUavSue6JIh/G47p2
1040+UqXj1zvccsFyHwszP3fuzJyxyVOSxTMcdzA/bxldvmBWo6+/XSsFRb42UxtqZNdM
1041+GIYBZQQ+Y2g6AMhbaCqTJO5B6f35mWTsYuFZK4EzQtqb4KaNfGkiBt0Il+Blk6G5
1042+k0CY6q4RAiu2dClrQewc
1043+=IfTS
1044+-----END PGP SIGNATURE-----
1045diff --git a/gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/main/source/Sources b/gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/main/source/Sources
1046new file mode 100644
1047index 0000000..04efb3f
1048--- /dev/null
1049+++ b/gitubuntu/apt_repo_test/inline.no-hash/dists/bionic/main/source/Sources
1050@@ -0,0 +1 @@
1051+sources-content
1052diff --git a/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release b/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release
1053new file mode 100644
1054index 0000000..3ef3c01
1055--- /dev/null
1056+++ b/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release
1057@@ -0,0 +1,13 @@
1058+Date: Fri, 23 Feb 2018 15:41:34 UTC
1059+MD5Sum:
1060+ 96cf5221942bbdd05baa3c1a7da738f2 36 Release
1061+ efcc6e6d5e421f11a17c47c61b5918a8 16 main/source/Sources
1062+SHA1:
1063+ b9c980e63fc0e02f0a48763e4498778d58e392f6 36 Release
1064+ 29ecd6b099df45721dbf0169d574fd7cf0b77fb1 16 main/source/Sources
1065+SHA256:
1066+ 1b4b9f56a80c231ea7e4d5a036903e4f9ccd690bf6845404ea3db21e22ddf647 36 Release
1067+ 106acf8f3542252ebbd46ea8ca10719d847208c2067c483a8f4568e70bde41b1 16 main/source/Sources
1068+SHA512:
1069+ 529a92dd8e2d35cfd50ffa2dd93023ebd4c26005ad4430772943225d8276aa828686b8744a5f4afcc7a2183441ffb61eb94056d1d63e1d5cdf66e242c2a11940 36 Release
1070+ f62f22397280f07185a0f12122b7c757596a8b9fc34b798aad877ea27a96919ed14ca64bbedeea8f21baf44472e7c1fad398866e5ef41b79d89508da0d3180d6 16 main/source/Sources
1071diff --git a/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release.gpg b/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release.gpg
1072new file mode 100644
1073index 0000000..b92cf3f
1074--- /dev/null
1075+++ b/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/Release.gpg
1076@@ -0,0 +1,16 @@
1077+-----BEGIN PGP SIGNATURE-----
1078+
1079+iQIcBAABCAAGBQJakDZQAAoJEN8hzJEp/3jmC4oQAMFRCyWlJGXdoogJfaW8bs9F
1080+biYcRquy+3tRk0Q4DgxedDBF/A6z1mq2ZHsF5q1pWMMPwqHhM38gz7Q7esvLxOGi
1081+7ITNakOZxHdlJOmp8ALm8fPb9HQ9+3xSrymA6Et+M+5If7EC1i9M7tKGT+lC7Mqa
1082+s2Aqw3xuJodI+FBiPm+Q/n4/5/QWAqRziuStvPnFv9UE923gMXfYvosoPXH6QRlq
1083+vCmxmHIb3szb5yaRACyhYRJ5/grhmAq7XL5VUlMMBxIRrESWB9WY+CcH2E/4oxOp
1084+RJlpFaQhW/3LrCTDVGxDK/x1av1lJYmEmZySyAjm7+QVaTvi7Xiqe0KYFLcyObck
1085+dOShT2InaCQPU9v8vdetRg6J6Xj9lZAQoGIKv06/dHVcjnIeW/Y41wa2AroWoYI1
1086+Cwx0qBxATthX4BXsqsoNkDiRyBJz0KwAna9sIX96QpKBJZjZaKlOetYTGcy+6Xt5
1087+UlYfWHqCKwhmTlbvG2t8diS7HICsxr46Utp42N8oX8mL1fXVDLuSGTQLSu8Cy87t
1088+ZwRBTE1U5JEgii0zYMTb1P9UOD8SEd52vv17P02KdRnbso3agMVsUwE63VmshjI/
1089+QSoqVPmo7SL9h+rj3GYRzBfzKH/c7w9Wo2tlXqKEtmulmRdlH1p+2OYYmC+eLj7M
1090+XNs2b+cmAqgF/JS0sZ8n
1091+=/Hli
1092+-----END PGP SIGNATURE-----
1093diff --git a/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/main/source/Sources b/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/main/source/Sources
1094new file mode 100644
1095index 0000000..f46f8f6
1096--- /dev/null
1097+++ b/gitubuntu/apt_repo_test/no-hash.badfile/dists/bionic/main/source/Sources
1098@@ -0,0 +1 @@
1099+sources-content-corrupted
1100diff --git a/gitubuntu/apt_repo_test/nosig.bare/dists/bionic/Release b/gitubuntu/apt_repo_test/nosig.bare/dists/bionic/Release
1101new file mode 100644
1102index 0000000..bdf6a0c
1103--- /dev/null
1104+++ b/gitubuntu/apt_repo_test/nosig.bare/dists/bionic/Release
1105@@ -0,0 +1 @@
1106+This file is not signed, so should be rejected without any attempt to parse it.
1107diff --git a/gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release b/gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release
1108new file mode 100644
1109index 0000000..bdf6a0c
1110--- /dev/null
1111+++ b/gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release
1112@@ -0,0 +1 @@
1113+This file is not signed, so should be rejected without any attempt to parse it.
1114diff --git a/gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release.gpg b/gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release.gpg
1115new file mode 100644
1116index 0000000..e69de29
1117--- /dev/null
1118+++ b/gitubuntu/apt_repo_test/nosig.detached-empty/dists/bionic/Release.gpg
1119diff --git a/gitubuntu/apt_repo_test/nosig.inline/dists/bionic/InRelease b/gitubuntu/apt_repo_test/nosig.inline/dists/bionic/InRelease
1120new file mode 100644
1121index 0000000..bdf6a0c
1122--- /dev/null
1123+++ b/gitubuntu/apt_repo_test/nosig.inline/dists/bionic/InRelease
1124@@ -0,0 +1 @@
1125+This file is not signed, so should be rejected without any attempt to parse it.
1126diff --git a/gitubuntu/apt_repo_test/nothing/README b/gitubuntu/apt_repo_test/nothing/README
1127new file mode 100644
1128index 0000000..8469453
1129--- /dev/null
1130+++ b/gitubuntu/apt_repo_test/nothing/README
1131@@ -0,0 +1,4 @@
1132+This directory is intentionally blank, and this file doubles as a means to have
1133+git maintain the directory. An attempt to read Release, InRelease, Release.gpg
1134+etc will always fail, regardless of what subdirectory we try, and this should
1135+cause the appropriate error.
1136diff --git a/gitubuntu/apt_repo_test/privkey.asc b/gitubuntu/apt_repo_test/privkey.asc
1137new file mode 100644
1138index 0000000..6f3a90c
1139--- /dev/null
1140+++ b/gitubuntu/apt_repo_test/privkey.asc
1141@@ -0,0 +1,105 @@
1142+-----BEGIN PGP PRIVATE KEY BLOCK-----
1143+
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
1245+=Hpvb
1246+-----END PGP PRIVATE KEY BLOCK-----
1247diff --git a/gitubuntu/apt_repo_test/pubkey.asc b/gitubuntu/apt_repo_test/pubkey.asc
1248new file mode 100644
1249index 0000000..ae2e9f8
1250--- /dev/null
1251+++ b/gitubuntu/apt_repo_test/pubkey.asc
1252@@ -0,0 +1,51 @@
1253+-----BEGIN PGP PUBLIC KEY BLOCK-----
1254+
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
1302+=QWc2
1303+-----END PGP PUBLIC KEY BLOCK-----
1304diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
1305index 9bf85a3..38ec2d2 100644
1306--- a/snap/snapcraft.yaml
1307+++ b/snap/snapcraft.yaml
1308@@ -257,6 +257,57 @@ parts:
1309 stage-packages:
1310 - distro-info
1311 after: [python3]
1312+ libgpg-error:
1313+ plugin: autotools
1314+ source: https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.27.tar.bz2
1315+ source-type: tar
1316+ configflags: [--prefix=/usr]
1317+ stage:
1318+ - -usr/share/info
1319+ libgcrypt:
1320+ plugin: autotools
1321+ source: https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.8.1.tar.bz2
1322+ source-type: tar
1323+ configflags: [--prefix=/usr]
1324+ stage:
1325+ - -usr/share/info
1326+ libassuan:
1327+ plugin: autotools
1328+ source: https://gnupg.org/ftp/gcrypt/libassuan/libassuan-2.5.1.tar.bz2
1329+ source-type: tar
1330+ configflags: [--prefix=/usr]
1331+ after: [libgpg-error]
1332+ stage:
1333+ - -usr/share/info
1334+ libksba:
1335+ plugin: autotools
1336+ source: https://gnupg.org/ftp/gcrypt/libksba/libksba-1.3.5.tar.bz2
1337+ source-type: tar
1338+ configflags: [--prefix=/usr]
1339+ stage:
1340+ - -usr/share/info
1341+ npth:
1342+ plugin: autotools
1343+ source: https://gnupg.org/ftp/gcrypt/npth/npth-1.5.tar.bz2
1344+ source-type: tar
1345+ configflags: [--prefix=/usr]
1346+ stage:
1347+ - -usr/share/info
1348+ gnupg2:
1349+ plugin: autotools
1350+ source: https://gnupg.org/ftp/gcrypt/gnupg/gnupg-2.2.4.tar.bz2
1351+ source-type: tar
1352+ configflags:
1353+ - --prefix=/usr
1354+ - --enable-gpg2-is-gpg
1355+ after:
1356+ - libgpg-error
1357+ - libgcrypt
1358+ - libassuan
1359+ - libksba
1360+ - npth
1361+ stage:
1362+ - -usr/share/info
1363 devscripts:
1364 plugin: nil
1365 stage-packages:
1366@@ -310,6 +361,14 @@ parts:
1367 - -lib/python3.6/site-packages/oauth*
1368 - -lib/python3.6/site-packages/launchpadlib*
1369 - -usr/lib/python3.6
1370+ - -usr/bin/gpg-error*
1371+ - -usr/share/aclocal/gpg-error.m4
1372+ - -usr/bin/dumpsexp
1373+ - -usr/bin/hmac256
1374+ - -usr/bin/libgcrypt-config
1375+ - -usr/bin/mpicalc
1376+ - -usr/include/gcrypt.h
1377+ - -usr/share/aclocal/libgcrypt.m4
1378 prime:
1379 - -usr/share/doc
1380 install: |

Subscribers

People subscribed via source and target branches