cli/pkg/cmd/attestation/verify/attestation.go
Meredith Lancaster 13dafefcb5 add missing nil struct checks and udpate error messages
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-04-01 11:23:25 -06:00

92 lines
2.8 KiB
Go

package verify
import (
"errors"
"fmt"
"github.com/cli/cli/v2/internal/text"
"github.com/cli/cli/v2/pkg/cmd/attestation/api"
"github.com/cli/cli/v2/pkg/cmd/attestation/artifact"
"github.com/cli/cli/v2/pkg/cmd/attestation/verification"
)
func getAttestations(o *Options, a artifact.DigestedArtifact) ([]*api.Attestation, string, error) {
// Fetch attestations from GitHub API within this if block since predicate type
// filter is done when the API is called
if o.FetchAttestationsFromGitHubAPI() {
if o.APIClient == nil {
errMsg := "✗ No APIClient provided"
return nil, errMsg, errors.New(errMsg)
}
params := api.FetchParams{
Digest: a.DigestWithAlg(),
Limit: o.Limit,
Owner: o.Owner,
PredicateType: o.PredicateType,
Repo: o.Repo,
}
attestations, err := o.APIClient.GetByDigest(params)
if err != nil {
msg := "✗ Loading attestations from GitHub API failed"
return nil, msg, err
}
pluralAttestation := text.Pluralize(len(attestations), "attestation")
msg := fmt.Sprintf("Loaded %s from GitHub API", pluralAttestation)
return attestations, msg, nil
}
// Fetch attestations from local bundle or OCI registry
// Predicate type filtering is done after the attestations are fetched
var attestations []*api.Attestation
var err error
var errMsg string
if o.BundlePath != "" {
attestations, err = verification.GetLocalAttestations(o.BundlePath)
if err != nil {
errMsg = fmt.Sprintf("✗ Loading attestations from %s failed", a.URL)
}
} else if o.UseBundleFromRegistry {
attestations, err = verification.GetOCIAttestations(o.OCIClient, a)
if err != nil {
errMsg = "✗ Loading attestations from OCI registry failed"
}
}
if err != nil {
return nil, errMsg, err
}
filtered, err := verification.FilterAttestations(o.PredicateType, attestations)
if err != nil {
return nil, err.Error(), err
}
pluralAttestation := text.Pluralize(len(filtered), "attestation")
msg := fmt.Sprintf("Loaded %s from %s", pluralAttestation, o.BundlePath)
return filtered, msg, nil
}
func verifyAttestations(art artifact.DigestedArtifact, att []*api.Attestation, sgVerifier verification.SigstoreVerifier, ec verification.EnforcementCriteria) ([]*verification.AttestationProcessingResult, string, error) {
sgPolicy, err := buildSigstoreVerifyPolicy(ec, art)
if err != nil {
logMsg := "✗ Failed to build Sigstore verification policy"
return nil, logMsg, err
}
sigstoreVerified, err := sgVerifier.Verify(att, sgPolicy)
if err != nil {
logMsg := "✗ Sigstore verification failed"
return nil, logMsg, err
}
// Verify extensions
certExtVerified, err := verification.VerifyCertExtensions(sigstoreVerified, ec)
if err != nil {
logMsg := "✗ Policy verification failed"
return nil, logMsg, err
}
return certExtVerified, "", nil
}