Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion features/__snapshots__/validate_image.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3525,7 +3525,7 @@ Error: error validating image ${REGISTRY}/acceptance/image of component Unnamed:
---

[PURL functions:stderr - 1]
time="${TIMESTAMP}" level=error msg="Parsing PURL \"this-is-not-a-valid-purl\" failed: purl scheme is not \"pkg\": \"\""
time="${TIMESTAMP}" level=error msg="failed to parse PURL" error="purl scheme is not \"pkg\": \"\"" function=ec.purl.parse purl=this-is-not-a-valid-purl
Error: success criteria not met

---
Expand Down
16 changes: 14 additions & 2 deletions internal/rego/purl/purl.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,29 +108,41 @@ func registerPURLParse() {
}

func purlIsValid(bctx rego.BuiltinContext, a *ast.Term) (*ast.Term, error) {
logger := log.WithField("function", purlIsValidName)

uri, ok := a.Value.(ast.String)
if !ok {
logger.Debug("input is not a string")
return ast.BooleanTerm(false), nil
}
logger = logger.WithField("purl", string(uri))

_, err := packageurl.FromString(string(uri))
if err != nil {
log.Debugf("Parsing PURL %s failed: %s", uri, err)
logger.WithField("error", err).Debug("failed to parse PURL")
return ast.BooleanTerm(false), nil
}
logger.Debug("PURL is valid")
return ast.BooleanTerm(true), nil
}

func purlParse(bctx rego.BuiltinContext, a *ast.Term) (*ast.Term, error) {
logger := log.WithField("function", purlParseName)

uri, ok := a.Value.(ast.String)
if !ok {
logger.Debug("input is not a string")
return nil, nil
}
logger = logger.WithField("purl", string(uri))

instance, err := packageurl.FromString(string(uri))
if err != nil {
log.Errorf("Parsing PURL %s failed: %s", uri, err)
logger.WithField("error", err).Error("failed to parse PURL")
return nil, nil
}

logger.Debug("successfully parsed PURL")
qualifiers := ast.NewArray()
for _, q := range instance.Qualifiers {
o := ast.NewObject(
Expand Down
17 changes: 17 additions & 0 deletions internal/rego/sigstore/sigstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/sigstore/cosign/v3/pkg/cosign"
"github.com/sigstore/cosign/v3/pkg/oci"
"github.com/sigstore/sigstore/pkg/tuf"
log "github.com/sirupsen/logrus"

"github.com/conforma/cli/internal/attestation"
"github.com/conforma/cli/internal/policy"
Expand Down Expand Up @@ -109,29 +110,37 @@ func registerSigstoreVerifyImage() {
}

func sigstoreVerifyImage(bctx rego.BuiltinContext, refTerm *ast.Term, optsTerm *ast.Term) (*ast.Term, error) {
logger := log.WithField("function", sigstoreVerifyImageName)
ctx := bctx.Context

uri, err := builtins.StringOperand(refTerm.Value, 0)
if err != nil {
logger.WithField("error", err).Debug("failed to get ref parameter")
return signatureFailedResult(fmt.Errorf("ref parameter: %w", err))
}
logger = logger.WithField("ref", string(uri))

ref, err := name.NewDigest(string(uri))
if err != nil {
logger.WithField("error", err).Debug("failed to create new digest")
return signatureFailedResult(fmt.Errorf("new digest: %w", err))
}

checkOpts, err := parseCheckOpts(ctx, optsTerm)
if err != nil {
logger.WithField("error", err).Debug("failed to parse check opts")
return signatureFailedResult(fmt.Errorf("opts parameter: %w", err))
}
checkOpts.ClaimVerifier = cosign.SimpleClaimVerifier

logger.Debug("verifying image signatures")
signatures, _, err := ecoci.NewClient(ctx).VerifyImageSignatures(ref, checkOpts)
if err != nil {
logger.WithField("error", err).Debug("failed to verify image signature")
return signatureFailedResult(fmt.Errorf("verify image signature: %w", err))
}

logger.WithField("signatures_count", len(signatures)).Debug("image signature verification complete")
return signatureResult(signatures, nil)
}

Expand Down Expand Up @@ -170,29 +179,37 @@ func registerSigstoreVerifyAttestation() {
}

func sigstoreVerifyAttestation(bctx rego.BuiltinContext, refTerm *ast.Term, optsTerm *ast.Term) (*ast.Term, error) {
logger := log.WithField("function", sigstoreVerifyAttestationName)
ctx := bctx.Context

uri, err := builtins.StringOperand(refTerm.Value, 0)
if err != nil {
logger.WithField("error", err).Debug("failed to get ref parameter")
return attestationFailedResult(fmt.Errorf("ref parameter: %w", err))
}
logger = logger.WithField("ref", string(uri))

ref, err := name.NewDigest(string(uri))
if err != nil {
logger.WithField("error", err).Debug("failed to create new digest")
return attestationFailedResult(fmt.Errorf("new digest: %w", err))
}

checkOpts, err := parseCheckOpts(ctx, optsTerm)
if err != nil {
logger.WithField("error", err).Debug("failed to parse check opts")
return attestationFailedResult(fmt.Errorf("opts parameter: %w", err))
}
checkOpts.ClaimVerifier = cosign.IntotoSubjectClaimVerifier

logger.Debug("verifying image attestations")
attestations, _, err := ecoci.NewClient(ctx).VerifyImageAttestations(ref, checkOpts)
if err != nil {
logger.WithField("error", err).Debug("failed to verify image attestation signature")
return attestationFailedResult(fmt.Errorf("verify image attestation signature: %w", err))
}

logger.WithField("attestations_count", len(attestations)).Debug("attestation verification complete")
return attestationResult(attestations, nil)
}

Expand Down
Loading