Compare --require-signature with the key that signed (closes #167)
check / check (push) Waiting to run
check / check (push) Waiting to run
check and fetch --require-signature compared the required fingerprint with the first key in the manifest's embedded public key block, while gpg accepted a good signature by any key in that block. Loading a signed manifest now refuses one whose embedded block holds more than one primary key, counted as gpg reads the block, or whose signer field is not the primary key fingerprint gpg reports for the signature. --require-signature compares with the signer field, which loading has checked. Signing names and embeds the key gpg reports it signed with, so a key ID matching several keys still writes a manifest that loads. docs/FORMAT.md states what a verifier checks. Model: opus-5-5
This commit is contained in:
+9
-16
@@ -126,10 +126,8 @@ func (mfa *CLIApp) fetchManifestToTemp(
|
||||
}
|
||||
|
||||
// verifyRequiredSigner enforces the --require-signature fingerprint
|
||||
// against the manifest's embedded signing key.
|
||||
func verifyRequiredSigner(
|
||||
ctx context.Context, chk *mfer.Checker, requiredSigner string,
|
||||
) error {
|
||||
// against the key that made the manifest's signature.
|
||||
func verifyRequiredSigner(chk *mfer.Checker, requiredSigner string) error {
|
||||
// Validate fingerprint format: must be exactly 40 hex characters
|
||||
if len(requiredSigner) != fingerprintHexLen {
|
||||
return fmt.Errorf("%w, got %d", errInvalidFingerprint, len(requiredSigner))
|
||||
@@ -145,22 +143,17 @@ func verifyRequiredSigner(
|
||||
errManifestNotSigned, requiredSigner)
|
||||
}
|
||||
|
||||
// Extract fingerprint from the embedded public key (not from the
|
||||
// signer field). This validates the key is importable and gets its
|
||||
// actual fingerprint.
|
||||
embeddedFP, err := chk.ExtractEmbeddedSigningKeyFP(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"failed to extract fingerprint from embedded signing key: %w", err)
|
||||
}
|
||||
// Loading the manifest checked that the signer is the fingerprint of
|
||||
// the key that made the signature.
|
||||
signer := string(chk.Signer())
|
||||
|
||||
// Compare fingerprints - must be exact match (case-insensitive)
|
||||
if !strings.EqualFold(embeddedFP, requiredSigner) {
|
||||
if !strings.EqualFold(signer, requiredSigner) {
|
||||
return fmt.Errorf("embedded signing key fingerprint %s %w %s",
|
||||
embeddedFP, errSignerMismatch, requiredSigner)
|
||||
signer, errSignerMismatch, requiredSigner)
|
||||
}
|
||||
|
||||
log.Infof("manifest signature verified (signer: %s)", embeddedFP)
|
||||
log.Infof("manifest signature verified (signer: %s)", signer)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -330,7 +323,7 @@ func (mfa *CLIApp) checkManifestOperation(
|
||||
// Check signature requirement
|
||||
requiredSigner := cmd.String(flagRequireSignature)
|
||||
if requiredSigner != "" {
|
||||
err = verifyRequiredSigner(ctx, chk, requiredSigner)
|
||||
err = verifyRequiredSigner(chk, requiredSigner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user