use utility to parse envelope, docs, use keyID

Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
This commit is contained in:
Ramon Petgrave
2024-06-18 20:23:24 +00:00
parent edde0a8aca
commit ead4e9bf4e
5 changed files with 34 additions and 39 deletions

10
go.mod
View File

@@ -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
View File

@@ -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=

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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