mirror of
https://github.com/slsa-framework/slsa-verifier.git
synced 2026-08-19 03:26:20 +00:00
Fixes #542 Adds support for VSAs. ## Testing process - added some unit an end-to-end tests - manually invoking ``` go run ./cli/slsa-verifier/ verify-vsa \ --subject-digest gce_image_id:8970095005306000053 \ --attestation-path ./cli/slsa-verifier/testdata/vsa/gce/v1/gke-gce-pre.bcid-vsa.jsonl \ --verifier-id https://bcid.corp.google.com/verifier/bcid_package_enforcer/v0.1 \ --resource-uri gce_image://gke-node-images:gke-12615-gke1418000-cos-101-17162-463-29-c-cgpv1-pre \ --verified-level BCID_L1 \ --verified-level SLSA_BUILD_LEVEL_2 \ --public-key-path ./cli/slsa-verifier/testdata/vsa/gce/v1/vsa_signing_public_key.pem \ --public-key-id keystore://76574:prod:vsa_signing_public_key \ --print-attestation {"_type":"https://in-toto.io/Statement/v1","predicateType":"https://slsa.dev/verification_summary/v1","predicate":{"timeVerified":"2024-06-12T07:24:34.351608Z","verifier":{"id":"https://bcid.corp.google.com/verifier/bcid_package_enforcer/v0.1"},"verificationResult":"PASSED","verifiedLevels":["BCID_L1","SLSA_BUILD_LEVEL_2"],"resourceUri":"gce_image://gke-node-images:gke-12615-gke1418000-cos-101-17162-463-29-c-cgpv1-pre","policy":{"uri":"googlefile:/google_src/files/642513192/depot/google3/production/security/bcid/software/gce_image/gke/vm_images.sw_policy.textproto"}},"subject":[{"name":"_","digest":{"gce_image_id":"8970095005306000053"}}]} Verifying VSA: PASSED PASSED: SLSA verification passed ``` TODOS: - open issue on the in_toto attestations repo about the incorrect json [fields](https://github.com/in-toto/attestation/blob/36c11295429a997d5bb520b4e80a1d0c16845f9c/go/predicates/vsa/v1/vsa.pb.go#L26-L40) for vsa 1.0 --------- Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
89 lines
2.8 KiB
Go
89 lines
2.8 KiB
Go
package verifiers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
|
"github.com/slsa-framework/slsa-verifier/v2/options"
|
|
"github.com/slsa-framework/slsa-verifier/v2/register"
|
|
_ "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gcb"
|
|
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha"
|
|
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/vsa"
|
|
"github.com/slsa-framework/slsa-verifier/v2/verifiers/utils"
|
|
)
|
|
|
|
func getVerifier(builderOpts *options.BuilderOpts) (register.SLSAVerifier, error) {
|
|
// By default, use the GHA builders
|
|
verifier := register.SLSAVerifiers[gha.VerifierName]
|
|
|
|
// If user provids a builderID, find the right verifier based on its ID.
|
|
if builderOpts.ExpectedID != nil &&
|
|
*builderOpts.ExpectedID != "" {
|
|
name, _, err := utils.ParseBuilderID(*builderOpts.ExpectedID, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, v := range register.SLSAVerifiers {
|
|
if v.IsAuthoritativeFor(name) {
|
|
return v, nil
|
|
}
|
|
}
|
|
// No builder found.
|
|
return nil, fmt.Errorf("%w: %s", serrors.ErrorVerifierNotSupported, *builderOpts.ExpectedID)
|
|
}
|
|
|
|
return verifier, nil
|
|
}
|
|
|
|
func VerifyImage(ctx context.Context, artifactImage string,
|
|
provenance []byte,
|
|
provenanceOpts *options.ProvenanceOpts,
|
|
builderOpts *options.BuilderOpts,
|
|
) ([]byte, *utils.TrustedBuilderID, error) {
|
|
verifier, err := getVerifier(builderOpts)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return verifier.VerifyImage(ctx, provenance, artifactImage, provenanceOpts, builderOpts)
|
|
}
|
|
|
|
func VerifyArtifact(ctx context.Context,
|
|
provenance []byte, artifactHash string,
|
|
provenanceOpts *options.ProvenanceOpts,
|
|
builderOpts *options.BuilderOpts,
|
|
) ([]byte, *utils.TrustedBuilderID, error) {
|
|
verifier, err := getVerifier(builderOpts)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return verifier.VerifyArtifact(ctx, provenance, artifactHash,
|
|
provenanceOpts, builderOpts)
|
|
}
|
|
|
|
func VerifyNpmPackage(ctx context.Context,
|
|
attestations []byte, tarballHash string,
|
|
provenanceOpts *options.ProvenanceOpts,
|
|
builderOpts *options.BuilderOpts,
|
|
) ([]byte, *utils.TrustedBuilderID, error) {
|
|
verifier, err := getVerifier(builderOpts)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return verifier.VerifyNpmPackage(ctx, attestations, tarballHash,
|
|
provenanceOpts, builderOpts)
|
|
}
|
|
|
|
// VerifyVSA verifies the VSA attestation. It returns the attestation base64-decoded from the envelope.
|
|
// We don't return a TrustedBuilderID. Instead, the user can user can parse the builderID separately, perhaps with
|
|
// https://pkg.go.dev/golang.org/x/mod/semver
|
|
func VerifyVSA(ctx context.Context,
|
|
attestation []byte,
|
|
vsaOpts *options.VSAOpts,
|
|
verificationOpts *options.VerificationOpts,
|
|
) ([]byte, error) {
|
|
return vsa.VerifyVSA(ctx, attestation, vsaOpts, verificationOpts)
|
|
}
|