mirror of
https://github.com/slsa-framework/slsa-verifier.git
synced 2026-02-14 09:39:54 +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](36c1129542/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)
|
|
}
|