1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
// Policy evaluation for prSigstoreSigned.
package signature
import (
"context"
"errors"
"fmt"
"strings"
"github.com/containers/image/v5/internal/private"
"github.com/containers/image/v5/internal/signature"
)
func (pr *prSigstoreSigned) isSignatureAuthorAccepted(ctx context.Context, image private.UnparsedImage, sig []byte) (signatureAcceptanceResult, *Signature, error) {
// We don’t know of a single user of this API, and we might return unexpected values in Signature.
// For now, just punt.
return sarRejected, nil, errors.New("isSignatureAuthorAccepted is not implemented for sigstore")
}
func (pr *prSigstoreSigned) isSignatureAccepted(ctx context.Context, image private.UnparsedImage, sig signature.Sigstore) (signatureAcceptanceResult, error) {
return sarRejected, errors.New(`Debian-local change: sigstore disabled`)
}
func (pr *prSigstoreSigned) isRunningImageAllowed(ctx context.Context, image private.UnparsedImage) (bool, error) {
sigs, err := image.UntrustedSignatures(ctx)
if err != nil {
return false, err
}
var rejections []error
foundNonSigstoreSignatures := 0
foundSigstoreNonAttachments := 0
for _, s := range sigs {
sigstoreSig, ok := s.(signature.Sigstore)
if !ok {
foundNonSigstoreSignatures++
continue
}
if sigstoreSig.UntrustedMIMEType() != signature.SigstoreSignatureMIMEType {
foundSigstoreNonAttachments++
continue
}
var reason error
switch res, err := pr.isSignatureAccepted(ctx, image, sigstoreSig); res {
case sarAccepted:
// One accepted signature is enough.
return true, nil
case sarRejected:
reason = err
case sarUnknown:
// Huh?! This should not happen at all; treat it as any other invalid value.
fallthrough
default:
reason = fmt.Errorf(`Internal error: Unexpected signature verification result "%s"`, string(res))
}
rejections = append(rejections, reason)
}
var summary error
switch len(rejections) {
case 0:
if foundNonSigstoreSignatures == 0 && foundSigstoreNonAttachments == 0 {
// A nice message for the most common case.
summary = PolicyRequirementError("A signature was required, but no signature exists")
} else {
summary = PolicyRequirementError(fmt.Sprintf("A signature was required, but no signature exists (%d non-sigstore signatures, %d sigstore non-signature attachments)",
foundNonSigstoreSignatures, foundSigstoreNonAttachments))
}
case 1:
summary = rejections[0]
default:
var msgs []string
for _, e := range rejections {
msgs = append(msgs, e.Error())
}
summary = PolicyRequirementError(fmt.Sprintf("None of the signatures were accepted, reasons: %s",
strings.Join(msgs, "; ")))
}
return false, summary
}
|