Skip to content

Commit

Permalink
Merge branch 'main' into ramonpetgrave64-lib-api
Browse files Browse the repository at this point in the history
  • Loading branch information
ramonpetgrave64 committed Aug 28, 2024
2 parents a1d45cc + 767ecf9 commit 74bf48e
Show file tree
Hide file tree
Showing 9 changed files with 390 additions and 91 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- [Verification for GitHub builders](#verification-for-github-builders)
- [Artifacts](#artifacts)
- [Containers](#containers)
- [The verify-image command](#the-verify-image-command)
- [npm packages](#npm-packages)
- [The verify-npm-package command](#the-verify-npm-package-command)
- [npm packages built using the SLSA3 Node.js builder](#npm-packages-built-using-the-slsa3-nodejs-builder)
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/slsa-framework/slsa-github-generator v1.9.0
github.com/spf13/cobra v1.8.1
golang.org/x/mod v0.19.0
sigs.k8s.io/release-utils v0.7.7
sigs.k8s.io/release-utils v0.8.4
)

require (
Expand Down Expand Up @@ -53,7 +53,7 @@ require (
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 // indirect
github.com/docker/cli v24.0.7+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v26.1.4+incompatible // indirect
github.com/docker/docker v26.1.5+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
Expand All @@ -74,7 +74,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1x
github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU=
github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v26.1.5+incompatible h1:NEAxTwEjxV6VbBMBoGG3zPqbiJosIApZjxlbrG9q3/g=
github.com/docker/docker v26.1.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
github.com/docker/go v1.5.1-1 h1:hr4w35acWBPhGBXlzPoHpmZ/ygPjnmFVxGxxGnMyP7k=
Expand Down Expand Up @@ -345,8 +345,8 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand Down Expand Up @@ -682,12 +682,12 @@ k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/release-utils v0.7.7 h1:JKDOvhCk6zW8ipEOkpTGDH/mW3TI+XqtPp16aaQ79FU=
sigs.k8s.io/release-utils v0.7.7/go.mod h1:iU7DGVNi3umZJ8q6aHyUFzsDUIaYwNnNKGHo3YE5E3s=
sigs.k8s.io/release-utils v0.8.4 h1:4QVr3UgbyY/d9p74LBhg0njSVQofUsAZqYOzVZBhdBw=
sigs.k8s.io/release-utils v0.8.4/go.mod h1:m1bHfscTemQp+z+pLCZnkXih9n0+WukIUU70n6nFnU0=
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk=
sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
Expand Down
54 changes: 4 additions & 50 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
"devDependencies": {
"markdown-toc": "1.2.0",
"renovate": "37.374.1"
},
"overrides": {
"autolinker": "^4.0.0"
}
}
50 changes: 38 additions & 12 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,56 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:best-practices", "schedule:monthly"],
"extends": [
"config:best-practices",
"schedule:monthly"
],
"vulnerabilityAlerts": {
"schedule": "before 4am"
},
"postUpdateOptions": ["gomodTidy", "gomodUpdateImportPaths"],
"postUpdateOptions": [
"gomodTidy",
"gomodUpdateImportPaths"
],
"packageRules": [
{
"matchManagers": ["github-actions"],
"matchManagers": [
"github-actions"
],
"groupName": "github-actions"
},
{
"matchManagers": ["gomod"],
"excludePackageNames": ["go"],
"matchUpdateTypes": ["minor", "patch"],
"groupName": "go"
"matchManagers": [
"gomod"
],
"matchUpdateTypes": [
"minor",
"patch"
],
"groupName": "go",
"matchPackageNames": [
"!go"
]
},
{
"matchManagers": ["npm"],
"matchDepTypes": ["dependencies"],
"matchUpdateTypes": ["minor", "patch"],
"matchManagers": [
"npm"
],
"matchDepTypes": [
"dependencies"
],
"matchUpdateTypes": [
"minor",
"patch"
],
"groupName": "npm"
},
{
"matchManagers": ["npm"],
"matchDepTypes": ["devDependencies"],
"matchManagers": [
"npm"
],
"matchDepTypes": [
"devDependencies"
],
"groupName": "npm dev"
}
]
Expand Down
81 changes: 66 additions & 15 deletions verifiers/internal/gha/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"fmt"
"slices"

dsselib "github.com/secure-systems-lab/go-securesystemslib/dsse"
bundle_v1 "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1"
Expand All @@ -20,7 +21,10 @@ import (
// Bundle specific errors.
var (
ErrorMismatchSignature = errors.New("bundle tlog entry does not match signature")
ErrorUnequalSignatures = errors.New("bundle tlog entry and envelope have an unequal number of signatures")
ErrorNoSignatures = errors.New("envolope has no signatures")
ErrorUnexpectedEntryType = errors.New("unexpected tlog entry type")
ErrorParsingEntryBody = errors.New("unexpected layout of the bundle tlog entry body")
ErrorMissingCertInBundle = errors.New("missing signing certificate in bundle")
ErrorUnexpectedBundleContent = errors.New("expected DSSE bundle content")
)
Expand Down Expand Up @@ -110,29 +114,41 @@ func getLeafCertFromBundle(bundle *bundle_v1.Bundle) (*x509.Certificate, error)
// DSSE envelope. It MUST verify that the signatures match to ensure that the
// tlog timestamp attests to the signature creation time.
func matchRekorEntryWithEnvelope(tlogEntry *v1.TransparencyLogEntry, env *dsselib.Envelope) error {
if len(env.Signatures) == 0 {
return ErrorNoSignatures
}

kindVersion := tlogEntry.GetKindVersion()
if kindVersion.Kind != "intoto" &&
kindVersion.Version != "0.0.2" {
return fmt.Errorf("%w: expected intoto:0.0.2, got %s:%s", ErrorUnexpectedEntryType,
kindVersion.Kind, kindVersion.Version)

if kindVersion.Kind == "intoto" && kindVersion.Version == "0.0.2" {
return matchRekorEntryWithEnvelopeIntotov002(tlogEntry, env)
}

if kindVersion.Kind == "dsse" && kindVersion.Version == "0.0.1" {
return matchRekorEntryWithEnvelopeDSSEv001(tlogEntry, env)
}

return fmt.Errorf("%w: wanted either intoto v0.0.2 or dsse v0.0.1, got: %s %s", ErrorUnexpectedEntryType, kindVersion.Kind, kindVersion.Version)
}

// matchRekorEntryWithEnvelopeDSSEv001 handles matchRekorEntryWithEnvelope for the intoto v0.0.1 type version.
func matchRekorEntryWithEnvelopeIntotov002(tlogEntry *v1.TransparencyLogEntry, env *dsselib.Envelope) error {
canonicalBody := tlogEntry.GetCanonicalizedBody()
var toto models.Intoto
var intotoObj models.IntotoV002Schema
if err := json.Unmarshal(canonicalBody, &toto); err != nil {
return fmt.Errorf("%w: %s", ErrorUnexpectedEntryType, err)
return fmt.Errorf("%w: %s", ErrorParsingEntryBody, err)
}
specMarshal, err := json.Marshal(toto.Spec)
if err != nil {
return fmt.Errorf("%w: %s", ErrorUnexpectedEntryType, err)
return fmt.Errorf("%w: %s", ErrorParsingEntryBody, err)
}
if err := json.Unmarshal(specMarshal, &intotoObj); err != nil {
return fmt.Errorf("%w: %s", ErrorUnexpectedEntryType, err)
return fmt.Errorf("%w: %s", ErrorParsingEntryBody, err)
}

if len(env.Signatures) != len(intotoObj.Content.Envelope.Signatures) {
return fmt.Errorf("expected %d sigs in canonical body, got %d",
return fmt.Errorf("%w: wanted %d, got %d", ErrorUnequalSignatures,
len(env.Signatures),
len(intotoObj.Content.Envelope.Signatures))
}
Expand All @@ -142,20 +158,55 @@ func matchRekorEntryWithEnvelope(tlogEntry *v1.TransparencyLogEntry, env *dsseli
// The signature in the canonical body is double base64-encoded.
encodedEnvSig := base64.StdEncoding.EncodeToString(
[]byte(sig.Sig))
var matchCanonical bool
for _, canonicalSig := range intotoObj.Content.Envelope.Signatures {
if canonicalSig.Sig.String() == encodedEnvSig {
matchCanonical = true
}
}
if !matchCanonical {
if !slices.ContainsFunc(
intotoObj.Content.Envelope.Signatures,
func(canonicalSig *models.IntotoV002SchemaContentEnvelopeSignaturesItems0) bool {
return canonicalSig.Sig.String() == encodedEnvSig
},
) {
return ErrorMismatchSignature
}
}

return nil
}

// matchRekorEntryWithEnvelopeDSSEv001 handles matchRekorEntryWithEnvelope for the dsse v0.0.1 type version.
func matchRekorEntryWithEnvelopeDSSEv001(tlogEntry *v1.TransparencyLogEntry, env *dsselib.Envelope) error {
canonicalBody := tlogEntry.GetCanonicalizedBody()
var dsseObj models.DSSE
if err := json.Unmarshal(canonicalBody, &dsseObj); err != nil {
return fmt.Errorf("%w: %s", ErrorParsingEntryBody, err)
}
var dsseSchemaObj models.DSSEV001Schema

specMarshal, err := json.Marshal(dsseObj.Spec)
if err != nil {
return fmt.Errorf("%w: %s", ErrorParsingEntryBody, err)
}
if err := json.Unmarshal(specMarshal, &dsseSchemaObj); err != nil {
return fmt.Errorf("%w: %s", ErrorParsingEntryBody, err)
}

if len(env.Signatures) != len(dsseSchemaObj.Signatures) {
return fmt.Errorf("%w: wanted %d, got %d", ErrorUnequalSignatures,
len(env.Signatures),
len(dsseSchemaObj.Signatures))
}
// TODO(#487): verify the certs match.
for _, sig := range env.Signatures {
if !slices.ContainsFunc(
dsseSchemaObj.Signatures,
func(canonicalSig *models.DSSEV001SchemaSignaturesItems0) bool {
return *canonicalSig.Signature == sig.Sig
},
) {
return ErrorMismatchSignature
}
}
return nil
}

// VerifyProvenanceBundle verifies the DSSE envelope using the offline Rekor bundle and
// returns the verified DSSE envelope containing the provenance
// and the signing certificate given the provenance.
Expand Down
Loading

0 comments on commit 74bf48e

Please sign in to comment.