mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-06 22:18:28 +00:00
Add SOURCE_DATE_EPOCH support for GPG signers
Both the external GPG signer (--faked-system-time) and internal Go
OpenPGP signer (signerConfig.Time) now honor SOURCE_DATE_EPOCH,
producing reproducible signatures alongside the plain Release file dates.
Adds system tests for both signer backends verifying byte-identical
Release, Release.gpg and InRelease across repeated publishes.
The signer tests (PublishRepo3[78]Test) are using an ed25519 key because
ed25519 signatures are deterministic by design. The Go openpgp library
uses a random nonce for DSA/ECDSA (see signature.go Sign calls using
config.Random() link below) so those signatures vary across runs
even with a fixed timestamp, making byte-identical verification impossible.
In addition to 49f342878a
Ref: https://github.com/aptly-dev/aptly/pull/1537
Ref: https://github.com/ProtonMail/go-crypto/blob/v1.4.0/openpgp/packet/signature.go#L945-L979
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
Loading packages...
|
||||
Generating metadata files and linking package files...
|
||||
Finalizing metadata files...
|
||||
Signing file 'Release' with gpg, please enter your passphrase when prompted:
|
||||
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
|
||||
|
||||
Local repo local-repo has been successfully published.
|
||||
Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing.
|
||||
Now you can add following line to apt sources:
|
||||
deb http://your-server/ maverick main
|
||||
deb-src http://your-server/ maverick main
|
||||
Don't forget to add your GPG key to apt with apt-key.
|
||||
|
||||
You can also use `aptly serve` to publish your repositories over HTTP quickly.
|
||||
@@ -0,0 +1,14 @@
|
||||
Loading packages...
|
||||
Generating metadata files and linking package files...
|
||||
Finalizing metadata files...
|
||||
openpgp: signing file 'Release'...
|
||||
openpgp: clearsigning file 'Release'...
|
||||
|
||||
Local repo local-repo has been successfully published.
|
||||
Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing.
|
||||
Now you can add following line to apt sources:
|
||||
deb http://your-server/ maverick main
|
||||
deb-src http://your-server/ maverick main
|
||||
Don't forget to add your GPG key to apt with apt-key.
|
||||
|
||||
You can also use `aptly serve` to publish your repositories over HTTP quickly.
|
||||
@@ -1024,3 +1024,77 @@ class PublishRepo37Test(BaseTest):
|
||||
# verify contents except of sums
|
||||
self.check_file_contents(
|
||||
'public/dists/maverick/Release', 'release', match_prepare=strip_processor)
|
||||
|
||||
|
||||
class PublishRepo38Test(BaseTest):
|
||||
"""
|
||||
publish repo: SOURCE_DATE_EPOCH produces reproducible GPG signatures (external gpg)
|
||||
"""
|
||||
fixtureCmds = [
|
||||
"aptly repo create local-repo",
|
||||
"aptly repo add local-repo ${files}",
|
||||
]
|
||||
runCmd = "aptly publish repo -gpg-provider=gpg -gpg-key=21DBB89C16DB3E6D -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick local-repo"
|
||||
gold_processor = BaseTest.expand_environ
|
||||
outputMatchPrepare = staticmethod(lambda s: "\n".join(l for l in s.split("\n") if not l.startswith("gpg:")))
|
||||
environmentOverride = {"SOURCE_DATE_EPOCH": "1750000000"}
|
||||
|
||||
def check(self):
|
||||
super(PublishRepo38Test, self).check()
|
||||
|
||||
# verify Release file date matches SOURCE_DATE_EPOCH
|
||||
release = self.read_file('public/dists/maverick/Release')
|
||||
date_line = [l for l in release.split("\n") if l.startswith("Date:")]
|
||||
if date_line[0] != "Date: Sun, 15 Jun 2025 15:06:40 UTC":
|
||||
raise Exception("expected Date from SOURCE_DATE_EPOCH, got: %s" % date_line[0])
|
||||
|
||||
# save all release artifacts from first publish
|
||||
first_release = self.read_file('public/dists/maverick/Release')
|
||||
first_release_gpg = self.read_file('public/dists/maverick/Release.gpg')
|
||||
first_inrelease = self.read_file('public/dists/maverick/InRelease')
|
||||
|
||||
# drop and republish with same SOURCE_DATE_EPOCH
|
||||
self.run_cmd("aptly publish drop maverick")
|
||||
self.run_cmd("aptly publish repo -gpg-provider=gpg -gpg-key=21DBB89C16DB3E6D -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick local-repo")
|
||||
|
||||
# verify byte-identical output for all release artifacts
|
||||
self.check_equal(first_release, self.read_file('public/dists/maverick/Release'))
|
||||
self.check_equal(first_release_gpg, self.read_file('public/dists/maverick/Release.gpg'))
|
||||
self.check_equal(first_inrelease, self.read_file('public/dists/maverick/InRelease'))
|
||||
|
||||
|
||||
class PublishRepo39Test(BaseTest):
|
||||
"""
|
||||
publish repo: SOURCE_DATE_EPOCH produces reproducible GPG signatures (internal signer, ed25519)
|
||||
"""
|
||||
fixtureCmds = [
|
||||
"aptly repo create local-repo",
|
||||
"aptly repo add local-repo ${files}",
|
||||
]
|
||||
runCmd = "aptly publish repo -gpg-key=BBF4E19434E91E4E -keyring=${files}/aptly-dual-binary.pub -secret-keyring=${files}/aptly3-binary.sec -distribution=maverick local-repo"
|
||||
gold_processor = BaseTest.expand_environ
|
||||
configOverride = {"gpgProvider": "internal"}
|
||||
environmentOverride = {"SOURCE_DATE_EPOCH": "1750000000"}
|
||||
|
||||
def check(self):
|
||||
super(PublishRepo39Test, self).check()
|
||||
|
||||
# verify Release file date matches SOURCE_DATE_EPOCH
|
||||
release = self.read_file('public/dists/maverick/Release')
|
||||
date_line = [l for l in release.split("\n") if l.startswith("Date:")]
|
||||
if date_line[0] != "Date: Sun, 15 Jun 2025 15:06:40 UTC":
|
||||
raise Exception("expected Date from SOURCE_DATE_EPOCH, got: %s" % date_line[0])
|
||||
|
||||
# save all release artifacts from first publish
|
||||
first_release = self.read_file('public/dists/maverick/Release')
|
||||
first_release_gpg = self.read_file('public/dists/maverick/Release.gpg')
|
||||
first_inrelease = self.read_file('public/dists/maverick/InRelease')
|
||||
|
||||
# drop and republish with same SOURCE_DATE_EPOCH
|
||||
self.run_cmd("aptly publish drop maverick")
|
||||
self.run_cmd("aptly publish repo -gpg-key=BBF4E19434E91E4E -keyring=${files}/aptly-dual-binary.pub -secret-keyring=${files}/aptly3-binary.sec -distribution=maverick local-repo")
|
||||
|
||||
# verify byte-identical output for all release artifacts
|
||||
self.check_equal(first_release, self.read_file('public/dists/maverick/Release'))
|
||||
self.check_equal(first_release_gpg, self.read_file('public/dists/maverick/Release.gpg'))
|
||||
self.check_equal(first_inrelease, self.read_file('public/dists/maverick/InRelease'))
|
||||
|
||||
Reference in New Issue
Block a user