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:
Tim Foerster
2026-03-03 12:58:43 +00:00
committed by André Roth
parent 3c068febde
commit d616977904
9 changed files with 121 additions and 18 deletions
+9
View File
@@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"syscall"
"time"
@@ -74,6 +75,14 @@ func (g *GoSigner) Init() error {
},
}
if epoch := os.Getenv("SOURCE_DATE_EPOCH"); epoch != "" {
if sec, err := strconv.ParseInt(epoch, 10, 64); err == nil {
t := time.Unix(sec, 0).UTC()
g.signerConfig.Time = func() time.Time { return t }
g.signerConfig.NonDeterministicSignaturesViaNotation = packet.BoolPointer(false)
}
}
if g.passphraseFile != "" {
passF, err := os.Open(g.passphraseFile)
if err != nil {