Add GPG signing support for manifest generation

- Add --sign-key flag and MFER_SIGN_KEY env var to gen and freshen commands
- Sign inner message multihash with GPG detached signature
- Include signer fingerprint and public key in outer wrapper
- Add comprehensive tests with temporary GPG keyring
- Increase test timeout to 10s for GPG key generation
This commit is contained in:
2025-12-18 02:12:54 -08:00
parent 308c583d57
commit 778999a285
10 changed files with 415 additions and 13 deletions
+14 -4
View File
@@ -50,9 +50,10 @@ type FileHashProgress struct {
// Builder constructs a manifest by adding files one at a time.
type Builder struct {
mu sync.Mutex
files []*MFFilePath
createdAt time.Time
mu sync.Mutex
files []*MFFilePath
createdAt time.Time
signingOptions *SigningOptions
}
// NewBuilder creates a new Builder.
@@ -165,6 +166,14 @@ func (b *Builder) AddFileWithHash(path RelFilePath, size FileSize, mtime ModTime
return nil
}
// SetSigningOptions sets the GPG signing options for the manifest.
// If opts is non-nil, the manifest will be signed when Build() is called.
func (b *Builder) SetSigningOptions(opts *SigningOptions) {
b.mu.Lock()
defer b.mu.Unlock()
b.signingOptions = opts
}
// Build finalizes the manifest and writes it to the writer.
func (b *Builder) Build(w io.Writer) error {
b.mu.Lock()
@@ -179,7 +188,8 @@ func (b *Builder) Build(w io.Writer) error {
// Create a temporary manifest to use existing serialization
m := &manifest{
pbInner: inner,
pbInner: inner,
signingOptions: b.signingOptions,
}
// Generate outer wrapper