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:
@@ -4,9 +4,11 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"github.com/multiformats/go-multihash"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
@@ -53,7 +55,10 @@ func (m *manifest) generateOuter() error {
|
||||
}
|
||||
|
||||
h := sha256.New()
|
||||
h.Write(innerData)
|
||||
if _, err := h.Write(innerData); err != nil {
|
||||
return err
|
||||
}
|
||||
sha256Hash := h.Sum(nil)
|
||||
|
||||
idc := new(bytes.Buffer)
|
||||
zw, err := zstd.NewWriter(idc, zstd.WithEncoderLevel(zstd.SpeedBestCompression))
|
||||
@@ -70,10 +75,38 @@ func (m *manifest) generateOuter() error {
|
||||
o := &MFFileOuter{
|
||||
InnerMessage: idc.Bytes(),
|
||||
Size: int64(len(innerData)),
|
||||
Sha256: h.Sum(nil),
|
||||
Sha256: sha256Hash,
|
||||
Version: MFFileOuter_VERSION_ONE,
|
||||
CompressionType: MFFileOuter_COMPRESSION_ZSTD,
|
||||
}
|
||||
|
||||
// Sign the manifest if signing options are provided
|
||||
if m.signingOptions != nil && m.signingOptions.KeyID != "" {
|
||||
// Encode hash as multihash for signing
|
||||
mh, err := multihash.Encode(sha256Hash, multihash.SHA2_256)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode multihash: %w", err)
|
||||
}
|
||||
|
||||
sig, err := gpgSign(mh, m.signingOptions.KeyID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to sign manifest: %w", err)
|
||||
}
|
||||
o.Signature = sig
|
||||
|
||||
fingerprint, err := gpgGetKeyFingerprint(m.signingOptions.KeyID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get key fingerprint: %w", err)
|
||||
}
|
||||
o.Signer = fingerprint
|
||||
|
||||
pubKey, err := gpgExportPublicKey(m.signingOptions.KeyID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to export public key: %w", err)
|
||||
}
|
||||
o.SigningPubKey = pubKey
|
||||
}
|
||||
|
||||
m.pbOuter = o
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user