Skip to content

Commit

Permalink
feat!: recurse through rekor subjects
Browse files Browse the repository at this point in the history
  • Loading branch information
Cole Kennedy authored and mikhailswift committed Apr 7, 2022
1 parent 4ab0f68 commit 539897c
Show file tree
Hide file tree
Showing 12 changed files with 462 additions and 52 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@ test/testapp
test/test-attestation.json
test/policy-signed.json
test/out.tar
test/sarif-report.json
test/sast.attestation.json
test/scorecard.attestation.json
test/scorecard.json
log
sarif-report.json
test/log
13 changes: 13 additions & 0 deletions cmd/witness/cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ const (
keybits = 512
)

func Test_loadOutfile(t *testing.T) {
outfile := "/tmp/outfile.txt"

f, err := loadOutfile(outfile)
if err != nil {
t.Errorf("unexpected error: %v", err)
}

if f.Name() != "/tmp/outfile.txt" {
t.Errorf("expected outfile to be /tmp/outfile.txt, got %s", f.Name())
}
}

func Test_loadSignersKeyPair(t *testing.T) {
privatePem, _ := rsakeypair(t)

Expand Down
4 changes: 2 additions & 2 deletions cmd/witness/cmd/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func Test_runRunRSACA(t *testing.T) {
t.Errorf("Error reading intermediate cert: %v", err)
}

if !bytes.Equal(b, envelopes[0].Signatures[0].Intermediates[0]) {
if !bytes.Equal(b, envelopes[0].Envelope.Signatures[0].Intermediates[0]) {
t.Errorf("Intermediates do not match")
}

Expand All @@ -156,7 +156,7 @@ func Test_runRunRSACA(t *testing.T) {
t.Errorf("Error reading leaf cert: %v", err)
}

if !bytes.Equal(b, envelopes[0].Signatures[0].Certificate) {
if !bytes.Equal(b, envelopes[0].Envelope.Signatures[0].Certificate) {
t.Errorf("Leaf cert does not match")
}

Expand Down
76 changes: 46 additions & 30 deletions cmd/witness/cmd/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ package cmd

import (
"crypto"
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"os"

"github.com/spf13/cobra"
"github.com/testifysec/witness/cmd/witness/options"
"github.com/testifysec/witness/pkg"
witness "github.com/testifysec/witness/pkg"
"github.com/testifysec/witness/pkg/cryptoutil"
"github.com/testifysec/witness/pkg/dsse"
"github.com/testifysec/witness/pkg/log"
"github.com/testifysec/witness/pkg/rekor"
)

Expand All @@ -46,6 +48,10 @@ func VerifyCmd() *cobra.Command {
return cmd
}

const (
MAX_DEPTH = 4
)

//todo: this logic should be broken out and moved to pkg/
//we need to abstract where keys are coming from, etc
func runVerify(vo options.VerifyOptions, args []string) error {
Expand All @@ -72,32 +78,58 @@ func runVerify(vo options.VerifyOptions, args []string) error {
return fmt.Errorf("could not unmarshal policy envelope: %w", err)
}

envelopes := make([]dsse.Envelope, 0)
diskEnvs, err := loadEnvelopesFromDisk(vo.AttestationFilePaths)
if err != nil {
return fmt.Errorf("failed to load attestation files: %w", err)
}

envelopes = append(envelopes, diskEnvs...)
verifiedEvidence := []witness.CollectionEnvelope{}

if vo.RekorServer != "" {

artifactDigestSet, err := cryptoutil.CalculateDigestSetFromFile(vo.ArtifactFilePath, []crypto.Hash{crypto.SHA256})
if err != nil {
return fmt.Errorf("failed to calculate artifact file's hash: %w", err)
}

rekorEnvs, err := loadEnvelopesFromRekor(vo.RekorServer, artifactDigestSet)
rc, err := rekor.New(vo.RekorServer)
if err != nil {
return fmt.Errorf("failed to get initialize Rekor client: %w", err)
}

digestSets := []cryptoutil.DigestSet{}
digestSets = append(digestSets, artifactDigestSet)

verifiers := []cryptoutil.Verifier{}
verifiers = append(verifiers, verifier)

evidence, err := rc.FindEvidence(digestSets, policyEnvelope, verifiers, diskEnvs, MAX_DEPTH)
if err != nil {
return fmt.Errorf("failed to find evidence: %w", err)
}

verifiedEvidence = append(verifiedEvidence, evidence...)
}

if vo.RekorServer == "" {
verifiedEvidence, err = witness.Verify(policyEnvelope, []cryptoutil.Verifier{verifier}, witness.VerifyWithCollectionEnvelopes(diskEnvs))
if err != nil {
return err
return fmt.Errorf("failed to verify policy: %w", err)

}
}

envelopes = append(envelopes, rekorEnvs...)
log.Info("Verification succeeded")
log.Info("Evidence:")
for i, e := range verifiedEvidence {
log.Info(fmt.Sprintf("%d: %s", i, e.Reference))
}
return nil

return witness.Verify(policyEnvelope, []cryptoutil.Verifier{verifier}, witness.VerifyWithCollectionEnvelopes(envelopes))
}

func loadEnvelopesFromDisk(paths []string) ([]dsse.Envelope, error) {
envelopes := make([]dsse.Envelope, 0)
func loadEnvelopesFromDisk(paths []string) ([]witness.CollectionEnvelope, error) {
envelopes := make([]witness.CollectionEnvelope, 0)
for _, path := range paths {
file, err := os.Open(path)
if err != nil {
Expand All @@ -114,31 +146,15 @@ func loadEnvelopesFromDisk(paths []string) ([]dsse.Envelope, error) {
if err := json.Unmarshal(fileBytes, &env); err != nil {
continue
}
envelopes = append(envelopes, env)
}

return envelopes, nil
}
h := sha256.Sum256(fileBytes)

func loadEnvelopesFromRekor(rekorServer string, artifactDigestSet cryptoutil.DigestSet) ([]dsse.Envelope, error) {
envelopes := make([]dsse.Envelope, 0)
rc, err := rekor.New(rekorServer)
if err != nil {
return nil, fmt.Errorf("failed to get initialize Rekor client: %w", err)
}

entries, err := rc.FindEntriesBySubject(artifactDigestSet)
if err != nil {
return nil, fmt.Errorf("failed to find any entries in rekor: %w", err)
}

for _, entry := range entries {
env, err := rekor.ParseEnvelopeFromEntry(entry)
if err != nil {
return nil, fmt.Errorf("failed to parse dsse envelope from rekor entry: %w", err)
collectionEnv := witness.CollectionEnvelope{
Envelope: env,
Reference: fmt.Sprintf("sha256:%x %s", h, path),
}

envelopes = append(envelopes, env)
envelopes = append(envelopes, collectionEnv)
}

return envelopes, nil
Expand Down
12 changes: 6 additions & 6 deletions cmd/witness/cmd/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ func Test_loadEnvelopesFromDisk(t *testing.T) {
t.Errorf("expected 1 envelope, got %d", len(envelopes))
}

if string(envelopes[0].Payload) != string(testPayload) {
t.Errorf("expected payload to be %s, got %s", string(testPayload), string(envelopes[0].Payload))
if string(envelopes[0].Envelope.Payload) != string(testPayload) {
t.Errorf("expected payload to be %s, got %s", string(testPayload), string(envelopes[0].Envelope.Payload))
}

if envelopes[0].PayloadType != "text" {
t.Errorf("expected payload type to be text, got %s", envelopes[0].PayloadType)
if envelopes[0].Envelope.PayloadType != "text" {
t.Errorf("expected payload type to be text, got %s", envelopes[0].Envelope.PayloadType)
}

if len(envelopes[0].Signatures) != 0 {
t.Errorf("expected 0 signatures, got %d", len(envelopes[0].Signatures))
if len(envelopes[0].Envelope.Signatures) != 0 {
t.Errorf("expected 0 signatures, got %d", len(envelopes[0].Envelope.Signatures))
}

err = os.RemoveAll("/tmp/witness")
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

replace github.com/sigstore/rekor => github.com/testifysec/rekor v0.4.0-dsse-intermediates
replace github.com/sigstore/rekor => github.com/testifysec/rekor v0.4.0-dsse-intermediates-2
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1491,8 +1491,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613/go.mod h1:g6AnIpDSYMcphz193otpSIzN+11Rs+AAIIC6rm1enug=
github.com/testifysec/rekor v0.4.0-dsse-intermediates h1:vbAA0ToJT9CJd9ZmjT/dJWoYXBCIpDbJReinXNpVJho=
github.com/testifysec/rekor v0.4.0-dsse-intermediates/go.mod h1:u9clLqaVjqV9pExVL1XkM37dGyMCOX/LMocS9nsnWDY=
github.com/testifysec/rekor v0.4.0-dsse-intermediates-2 h1:Kpf8sBke+KXvlxgsLuwFgXh3ogG5GN1bhOyMQGB0miU=
github.com/testifysec/rekor v0.4.0-dsse-intermediates-2/go.mod h1:u9clLqaVjqV9pExVL1XkM37dGyMCOX/LMocS9nsnWDY=
github.com/theupdateframework/go-tuf v0.0.0-20211203210025-7ded50136bf9 h1:Toe1Dy1nG62nh3CLZ6/izUrdgjhV/aGHvvu+uwGykxk=
github.com/theupdateframework/go-tuf v0.0.0-20211203210025-7ded50136bf9/go.mod h1:n2n6wwC9BEnYS/C/APAtNln0eM5zYAYOkOTx6VEG/mA=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
Expand Down
1 change: 1 addition & 0 deletions pkg/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type PublicKey struct {
type VerifiedStatement struct {
Verifiers []cryptoutil.Verifier
Statement intoto.Statement
Reference string
}

// PublicKeyVerifiers returns verifiers for each of the policy's embedded public keys grouped by the key's ID
Expand Down
Loading

0 comments on commit 539897c

Please sign in to comment.