Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add gitbom support #27

Merged
merged 3 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion attestation/aws-iid/aws-iid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func TestAttestor_Subjects(t *testing.T) {

imageid := sha256.Sum256([]byte("ami-5fb8c835"))
digest := res["imageid:ami-5fb8c835"]
h := digest[crypto.SHA256]
h := digest[cryptoutil.DigestValue{Hash: crypto.SHA256}]
h2 := hex.EncodeToString(imageid[:])
if h != h2 {
t.Errorf("Expected %s, got %s", h, h2)
Expand Down
26 changes: 26 additions & 0 deletions attestation/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"
"path/filepath"

"github.com/edwarnicke/gitoid"
"github.com/testifysec/go-witness/cryptoutil"
"github.com/testifysec/go-witness/log"
)
Expand Down Expand Up @@ -79,6 +80,31 @@ func RecordArtifacts(basePath string, baseArtifacts map[string]cryptoutil.Digest
return err
}

fileReader, err := os.Open(path)
if err != nil {
return err
}

goidSha1, err := gitoid.New(fileReader)
if err != nil {
return err
}

goidSha256, err := gitoid.New(fileReader, gitoid.WithSha256())
if err != nil {
return err
}

artifact[cryptoutil.DigestValue{
Hash: crypto.SHA1,
GitOID: true,
}] = goidSha1.URI()

artifact[cryptoutil.DigestValue{
Hash: crypto.SHA256,
GitOID: true,
}] = goidSha256.URI()

if shouldRecord(relPath, artifact, baseArtifacts) {
artifacts[relPath] = artifact
}
Expand Down
5 changes: 4 additions & 1 deletion attestation/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {
subjectName := fmt.Sprintf("commithash:%v", a.CommitHash)
return map[string]cryptoutil.DigestSet{
subjectName: {
crypto.SHA1: a.CommitHash,
{
Hash: crypto.SHA1,
GitOID: true,
}: a.CommitHash,
},
}
}
Expand Down
1 change: 0 additions & 1 deletion attestation/material/material.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package material

import (
"encoding/json"

"github.com/testifysec/go-witness/attestation"
"github.com/testifysec/go-witness/attestation/file"
"github.com/testifysec/go-witness/cryptoutil"
Expand Down
6 changes: 3 additions & 3 deletions attestation/oci/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ func (a *Attestor) parseMaifest(ctx *attestation.AttestationContext) error {
func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {
subj := make(map[string]cryptoutil.DigestSet)

subj[fmt.Sprintf("tardigest:%s", a.TarDigest[crypto.SHA256])] = a.TarDigest
subj[fmt.Sprintf("imageid:%s", a.ImageID[crypto.SHA256])] = a.ImageID
subj[fmt.Sprintf("tardigest:%s", a.TarDigest[cryptoutil.DigestValue{Hash: crypto.SHA256}])] = a.TarDigest
subj[fmt.Sprintf("imageid:%s", a.ImageID[cryptoutil.DigestValue{Hash: crypto.SHA256}])] = a.ImageID
//image tags
for _, tag := range a.ImageTags {
hash, err := cryptoutil.CalculateDigestSetFromBytes([]byte(tag), a.hashes)
Expand All @@ -242,7 +242,7 @@ func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {

//diff ids
for layer := range a.LayerDiffIDs {
subj[fmt.Sprintf("layerdiffid%02d:%s", layer, a.LayerDiffIDs[layer][crypto.SHA256])] = a.LayerDiffIDs[layer]
subj[fmt.Sprintf("layerdiffid%02d:%s", layer, a.LayerDiffIDs[layer][cryptoutil.DigestValue{Hash: crypto.SHA256}])] = a.LayerDiffIDs[layer]
}
return subj
}
Expand Down
10 changes: 5 additions & 5 deletions attestation/oci/oci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ func TestAttestor_Attest(t *testing.T) {

err = ctx.RunAttestors()

require.Equal(t, imageID, a.ImageID[crypto.SHA256])
require.Equal(t, diffID, a.LayerDiffIDs[0][crypto.SHA256])
require.Equal(t, imageID, a.ImageID[cryptoutil.DigestValue{Hash: crypto.SHA256}])
require.Equal(t, diffID, a.LayerDiffIDs[0][cryptoutil.DigestValue{Hash: crypto.SHA256}])
require.NoError(t, err)

}
Expand Down Expand Up @@ -157,9 +157,9 @@ func TestAttestor_Subjects(t *testing.T) {

subj := a.Subjects()

require.Equal(t, imageID, subj[fmt.Sprintf("imageid:%s", imageID)][crypto.SHA256])
require.Equal(t, diffID, subj[fmt.Sprintf("layerdiffid00:%s", diffID)][crypto.SHA256])
require.Equal(t, tarDigest[crypto.SHA256], subj["tardigest:a996818fbcd6d8ae9214fb1f8b3c0cacee64fc8c937b749db0782c482c0575ac"][crypto.SHA256])
require.Equal(t, imageID, subj[fmt.Sprintf("imageid:%s", imageID)][cryptoutil.DigestValue{Hash: crypto.SHA256}])
require.Equal(t, diffID, subj[fmt.Sprintf("layerdiffid00:%s", diffID)][cryptoutil.DigestValue{Hash: crypto.SHA256}])
require.Equal(t, tarDigest[cryptoutil.DigestValue{Hash: crypto.SHA256}], subj["tardigest:a996818fbcd6d8ae9214fb1f8b3c0cacee64fc8c937b749db0782c482c0575ac"][cryptoutil.DigestValue{Hash: crypto.SHA256}])

//require.Equal(t, tarDigest[crypto.SHA256], subj[fmt.Sprintf("tardigest:SHA256:%s", tarDigest)][crypto.SHA256])

Expand Down
7 changes: 3 additions & 4 deletions attestation/product/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ package product
import (
"encoding/json"
"fmt"
"net/http"
"os"

"github.com/testifysec/go-witness/attestation"
"github.com/testifysec/go-witness/attestation/file"
"github.com/testifysec/go-witness/cryptoutil"
"net/http"
"os"
)

const (
Expand Down Expand Up @@ -63,12 +62,12 @@ func fromDigestMap(digestMap map[string]cryptoutil.DigestSet) map[string]attesta
f.Close()
}

defer f.Close()
products[fileName] = attestation.Product{
MimeType: mimeType,
Digest: digestSet,
}
}

return products
}

Expand Down
2 changes: 1 addition & 1 deletion attestation/scorecard/scorecard.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {
subj := make(map[string]cryptoutil.DigestSet)

subj[commitSubj] = cryptoutil.DigestSet{
crypto.SHA1: a.Scorecard.Repo.Commit,
cryptoutil.DigestValue{Hash: crypto.SHA1}: a.Scorecard.Repo.Commit,
}

ds, err := cryptoutil.CalculateDigestSetFromBytes([]byte(nameSubj), a.hashes)
Expand Down
61 changes: 49 additions & 12 deletions cryptoutil/digestset.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,42 @@ import (
)

var (
hashNames = map[crypto.Hash]string{
crypto.SHA256: "sha256",
crypto.SHA1: "sha1",
}

hashesByName = map[string]crypto.Hash{
"sha256": crypto.SHA256,
"sha1": crypto.SHA1,
hashNames = map[DigestValue]string{
{
Hash: crypto.SHA256,
GitOID: false,
}: "sha256",
{
Hash: crypto.SHA1,
GitOID: false,
}: "sha1",
{
Hash: crypto.SHA256,
GitOID: true,
}: "gitoid:sha256",
{
Hash: crypto.SHA1,
GitOID: true,
}: "gitoid:sha1",
}

hashesByName = map[string]DigestValue{
"sha256": {
crypto.SHA256,
false,
},
"sha1": {
crypto.SHA1,
false,
},
"gitoid:sha256": {
crypto.SHA256,
true,
},
"gitoid:sha1": {
crypto.SHA1,
true,
},
}
)

Expand All @@ -42,10 +70,15 @@ func (e ErrUnsupportedHash) Error() string {
return fmt.Sprintf("unsupported hash function: %v", string(e))
}

type DigestSet map[crypto.Hash]string
type DigestValue struct {
crypto.Hash
GitOID bool
}

type DigestSet map[DigestValue]string

func HashToString(h crypto.Hash) (string, error) {
if name, ok := hashNames[h]; ok {
if name, ok := hashNames[DigestValue{Hash: h}]; ok {
return name, nil
}

Expand All @@ -54,7 +87,7 @@ func HashToString(h crypto.Hash) (string, error) {

func HashFromString(name string) (crypto.Hash, error) {
if hash, ok := hashesByName[name]; ok {
return hash, nil
return hash.Hash, nil
}

return crypto.Hash(0), ErrUnsupportedHash(name)
Expand Down Expand Up @@ -125,7 +158,11 @@ func CalculateDigestSet(r io.Reader, hashes []crypto.Hash) (DigestSet, error) {
}

for hash, hashfunc := range hashfuncs {
digestSet[hash] = string(HexEncode(hashfunc.Sum(nil)))
digestValue := DigestValue{
Hash: hash,
GitOID: false,
}
digestSet[digestValue] = string(HexEncode(hashfunc.Sum(nil)))
}
return digestSet, nil
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/digitorus/pkcs7 v0.0.0-20220704143225-a9c8106cbfc6
github.com/digitorus/timestamp v0.0.0-20220704143351-8225fba02d52
github.com/edwarnicke/gitoid v0.0.0-20220710194850-1be5bfda1f9d
github.com/go-git/go-git/v5 v5.4.2
github.com/open-policy-agent/opa v0.43.1
github.com/owenrumney/go-sarif v1.1.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@ github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdf
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/edwarnicke/gitoid v0.0.0-20220710194850-1be5bfda1f9d h1:4l+Uq5zFWSagXgGFaKRRVWJrnlzeathyagWgYUltCgY=
github.com/edwarnicke/gitoid v0.0.0-20220710194850-1be5bfda1f9d/go.mod h1:WxWwA3EYuCQjlR5EBUX3uaTS8bh9BOa7BcqVREHQ0uQ=
github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1 h1:/7G7q8SDJdrah5jDYqZI8pGFjSqiCzfSEO+NgqKCYX0=
github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
Expand Down
1 change: 0 additions & 1 deletion intoto/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package intoto

import (
"encoding/json"

"github.com/testifysec/go-witness/cryptoutil"
)

Expand Down
8 changes: 4 additions & 4 deletions policy/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ deny[msg] {
step1Collection := attestation.NewCollection("step1", []attestation.Attestor{commandRun})
step1CollectionJson, err := json.Marshal(&step1Collection)
require.NoError(t, err)
intotoStatement, err := intoto.NewStatement(attestation.CollectionType, step1CollectionJson, map[string]cryptoutil.DigestSet{"dummy": {crypto.SHA256: "dummy"}})
intotoStatement, err := intoto.NewStatement(attestation.CollectionType, step1CollectionJson, map[string]cryptoutil.DigestSet{"dummy": {cryptoutil.DigestValue{Hash: crypto.SHA256}: "dummy"}})
require.NoError(t, err)

_, err = policy.Verify(
Expand Down Expand Up @@ -220,8 +220,8 @@ func TestArtifacts(t *testing.T) {

dummySha := "a1073968266a4ed65472a80ebcfd31f1955cfdf8f23d439b1df84d78ce05f7a9"
path := "testfile"
mats := map[string]cryptoutil.DigestSet{path: {crypto.SHA256: dummySha}}
prods := map[string]attestation.Product{path: {Digest: cryptoutil.DigestSet{crypto.SHA256: dummySha}, MimeType: "application/text"}}
mats := map[string]cryptoutil.DigestSet{path: {cryptoutil.DigestValue{Hash: crypto.SHA256}: dummySha}}
prods := map[string]attestation.Product{path: {Digest: cryptoutil.DigestSet{cryptoutil.DigestValue{Hash: crypto.SHA256}: dummySha}, MimeType: "application/text"}}
step1Collection := attestation.NewCollection("step1", []attestation.Attestor{DummyProducer{prods}})
step2Collection := attestation.NewCollection("step2", []attestation.Attestor{DummyMaterialer{mats}})
step1CollectionJson, err := json.Marshal(step1Collection)
Expand Down Expand Up @@ -256,7 +256,7 @@ func TestArtifacts(t *testing.T) {
)
assert.NoError(t, err)

mats[path][crypto.SHA256] = "badhash"
mats[path][cryptoutil.DigestValue{Hash: crypto.SHA256}] = "badhash"
step2Collection = attestation.NewCollection("step2", []attestation.Attestor{DummyMaterialer{mats}})
step2CollectionJson, err = json.Marshal(step2Collection)
require.NoError(t, err)
Expand Down