mirror of
https://github.com/slsa-framework/slsa-verifier.git
synced 2026-05-16 13:36:33 +00:00
use utility to parse envelope, docs, use keyID
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
This commit is contained in:
10
go.mod
10
go.mod
@@ -18,6 +18,7 @@ require (
|
||||
require (
|
||||
github.com/google/go-containerregistry v0.19.1
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/in-toto/attestation v1.1.0
|
||||
github.com/sigstore/cosign/v2 v2.2.4
|
||||
github.com/sigstore/sigstore-go v0.2.0
|
||||
github.com/slsa-framework/slsa-github-generator v1.9.0
|
||||
@@ -33,7 +34,6 @@ require (
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/in-toto/attestation v1.1.0 // indirect
|
||||
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
@@ -108,13 +108,13 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/term v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
google.golang.org/grpc v1.62.1 // indirect
|
||||
google.golang.org/protobuf v1.34.1
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
||||
20
go.sum
20
go.sum
@@ -444,6 +444,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbm
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
|
||||
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
|
||||
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
|
||||
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
|
||||
github.com/sigstore/cosign/v2 v2.2.4 h1:iY4vtEacmu2hkNj1Fh+8EBqBwKs2DHM27/lbNWDFJro=
|
||||
@@ -561,8 +563,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w=
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -602,18 +604,18 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -644,8 +646,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
intotoAttestattions "github.com/in-toto/attestation/go/v1"
|
||||
intotoGolang "github.com/in-toto/in-toto-golang/in_toto"
|
||||
intotoCommon "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
|
||||
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
||||
@@ -20,7 +19,7 @@ const vsaPredicateType = "https://slsa.dev/verification_summary/v1"
|
||||
type VSA struct {
|
||||
intotoGolang.StatementHeader
|
||||
// Predicate is the VSA predicate.
|
||||
// Idealy, we use "github.com/in-toto/attestation/go/predicates/vsa/v1"'s VerfificationSummary,
|
||||
// Ideally, we use "github.com/in-toto/attestation/go/predicates/vsa/v1"'s VerfificationSummary,
|
||||
// but it currently does not correctly implement some fields according to spec, such as VerifiedLevels
|
||||
Predicate Predicate `json:"predicate"`
|
||||
}
|
||||
@@ -46,8 +45,8 @@ type Verifier struct {
|
||||
|
||||
// VSAFromStatement creates a VSA from a statement.
|
||||
func VSAFromStatement(statement *intotoGolang.Statement) (*VSA, error) {
|
||||
if err := validateStatementTypes(statement); err != nil {
|
||||
return nil, err
|
||||
if statement.PredicateType != vsaPredicateType {
|
||||
return nil, fmt.Errorf("%w: expected predicate type %q, got %q", serrors.ErrorInvalidDssePayload, vsaPredicateType, statement.PredicateType)
|
||||
}
|
||||
vsaBytes, err := json.Marshal(statement)
|
||||
if err != nil {
|
||||
@@ -59,14 +58,3 @@ func VSAFromStatement(statement *intotoGolang.Statement) (*VSA, error) {
|
||||
}
|
||||
return &vsa, nil
|
||||
}
|
||||
|
||||
// validateStatementTypes validates the statement types.
|
||||
func validateStatementTypes(statement *intotoGolang.Statement) error {
|
||||
if statement.Type != intotoAttestattions.StatementTypeUri {
|
||||
return fmt.Errorf("%w: expected statement type %q, got %q", serrors.ErrorInvalidDssePayload, intotoAttestattions.StatementTypeUri, statement.Type)
|
||||
}
|
||||
if statement.PredicateType != vsaPredicateType {
|
||||
return fmt.Errorf("%w: expected predicate type %q, got %q", serrors.ErrorInvalidDssePayload, vsaPredicateType, statement.PredicateType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -29,14 +29,6 @@ func VerifyVSA(ctx context.Context,
|
||||
sigstoreEnvelope := sigstoreBundle.Envelope{
|
||||
Envelope: envelope,
|
||||
}
|
||||
sigstoreStatement, err := sigstoreEnvelope.Statement()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
vsa, err := vsa10.VSAFromStatement(sigstoreStatement)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// verify the envelope. signature
|
||||
err = verifyEnvelopeSignature(ctx, &sigstoreEnvelope)
|
||||
@@ -46,6 +38,14 @@ func VerifyVSA(ctx context.Context,
|
||||
|
||||
// TODO:
|
||||
// verify the metadata
|
||||
statement, err := utils.StatementFromEnvelope(envelope)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
vsa, err := vsa10.VSAFromStatement(statement)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
err = matchExpectedValues(vsa, vsaOpts)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -61,6 +61,7 @@ func verifyEnvelopeSignature(ctx context.Context, sigstoreEnvelope *sigstoreBund
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeGa6ZCZn0q6WpaUwJrSk+PPYEsca
|
||||
3Xkk3UrxvbQtoZzTmq0zIYq+4QQl0YBedSyy+XcwAMaUWTouTrB05WhYtg==
|
||||
-----END PUBLIC KEY-----`)
|
||||
keyID := "keystore://76574:prod:vsa_signing_public_key"
|
||||
pubKey, err := sigstoreCryptoUtils.UnmarshalPEMToPublicKey(pubKeyBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %w", serrors.ErrorInvalidPublicKey, err)
|
||||
@@ -72,6 +73,7 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeGa6ZCZn0q6WpaUwJrSk+PPYEsca
|
||||
envelopeVerifier, err := dsse.NewEnvelopeVerifier(&sigstoreDSSE.VerifierAdapter{
|
||||
SignatureVerifier: signatureVerifier,
|
||||
Pub: pubKey,
|
||||
PubKeyID: keyID, // "keystore://76574:prod:vsa_signing_public_key"
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: creating verifier %w", serrors.ErrorInvalidPublicKey, err)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
intotoAttestattions "github.com/in-toto/attestation/go/v1"
|
||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||
dsselib "github.com/secure-systems-lab/go-securesystemslib/dsse"
|
||||
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
||||
@@ -42,13 +43,17 @@ func PayloadFromEnvelope(env *dsselib.Envelope) ([]byte, error) {
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
// StatementFromBytes parses the provided byte slice as a JSON payload and returns an intoto.Statement.
|
||||
// Ideally, we use the "V1" Statement in https://pkg.go.dev/github.com/in-toto/attestation/go/v1#pkg-constants,
|
||||
// but it parses json fields in snake case, while the official spec uses camel case
|
||||
// https://github.com/in-toto/attestation/blob/v1.0/spec/v1.0/statement.md.
|
||||
func StatementFromBytes(payload []byte) (*intoto.Statement, error) {
|
||||
var statement intoto.Statement
|
||||
if err := json.Unmarshal(payload, &statement); err != nil {
|
||||
return nil, fmt.Errorf("%w: %w", serrors.ErrorInvalidDssePayload, err)
|
||||
}
|
||||
|
||||
if statement.Type != intoto.StatementInTotoV01 {
|
||||
if statement.Type != intoto.StatementInTotoV01 && statement.Type != intotoAttestattions.StatementTypeUri {
|
||||
return nil, fmt.Errorf("%w: invalid statement type: %q", serrors.ErrorInvalidDssePayload, statement.Type)
|
||||
}
|
||||
return &statement, nil
|
||||
|
||||
Reference in New Issue
Block a user