Enforce real timeouts on gpg subprocess calls (closes #62)
check / check (push) Successful in 2m2s
check / check (push) Successful in 2m2s
Every gpg run now has a one-minute deadline (gpgTimeout) on top of its caller's context and is killed when either ends. A timeout is reported as "gpg timed out" under the failing operation instead of "signal: killed". Only gpg itself is killed; WaitDelay (one second) stops the run from waiting on a process gpg left behind that still holds its output, such as a wrapper script that does not exec the real gpg. Builder.Build and Checker.ExtractEmbeddedSigningKeyFP take a context, so ToManifest's context now reaches signing and the contextcheck suppression calling signing non-cancellable is gone. Manifest loading takes no context, so its signature check is bounded by the timeout alone. Model: opus-5-5
This commit was merged in pull request #119.
This commit is contained in:
+9
-8
@@ -2,6 +2,7 @@ package mfer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -50,13 +51,13 @@ func newTimestampFromTime(t time.Time) *Timestamp {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *manifest) generate() error {
|
||||
func (m *manifest) generate(ctx context.Context) error {
|
||||
if m.pbInner == nil {
|
||||
return errInnerNotSet
|
||||
}
|
||||
|
||||
if m.pbOuter == nil {
|
||||
e := m.generateOuter()
|
||||
e := m.generateOuter(ctx)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
@@ -77,7 +78,7 @@ func (m *manifest) generate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manifest) generateOuter() error {
|
||||
func (m *manifest) generateOuter(ctx context.Context) error {
|
||||
if m.pbInner == nil {
|
||||
return errInternal
|
||||
}
|
||||
@@ -135,7 +136,7 @@ func (m *manifest) generateOuter() error {
|
||||
|
||||
// Sign the manifest if signing options are provided
|
||||
if m.signingOptions != nil && m.signingOptions.KeyID != "" {
|
||||
return m.signOuter()
|
||||
return m.signOuter(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -143,27 +144,27 @@ func (m *manifest) generateOuter() error {
|
||||
|
||||
// signOuter signs the outer message with the configured GPG key and
|
||||
// embeds the signature, signer fingerprint, and public key.
|
||||
func (m *manifest) signOuter() error {
|
||||
func (m *manifest) signOuter(ctx context.Context) error {
|
||||
sigString, err := m.signatureString()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate signature string: %w", err)
|
||||
}
|
||||
|
||||
sig, err := gpgSign([]byte(sigString), m.signingOptions.KeyID)
|
||||
sig, err := gpgSign(ctx, []byte(sigString), m.signingOptions.KeyID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to sign manifest: %w", err)
|
||||
}
|
||||
|
||||
m.pbOuter.Signature = sig
|
||||
|
||||
fingerprint, err := gpgGetKeyFingerprint(m.signingOptions.KeyID)
|
||||
fingerprint, err := gpgGetKeyFingerprint(ctx, m.signingOptions.KeyID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get key fingerprint: %w", err)
|
||||
}
|
||||
|
||||
m.pbOuter.Signer = fingerprint
|
||||
|
||||
pubKey, err := gpgExportPublicKey(m.signingOptions.KeyID)
|
||||
pubKey, err := gpgExportPublicKey(ctx, m.signingOptions.KeyID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to export public key: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user