From 97adc5f1e382585a35a718c1807cf76277cfe500 Mon Sep 17 00:00:00 2001 From: cole kennedy Date: Tue, 22 Feb 2022 16:03:12 -0600 Subject: [PATCH] feat/sarif attestor --- go.mod | 6 +- go.sum | 7 ++ pkg/attestation/sarif/sarif.go | 119 +++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 pkg/attestation/sarif/sarif.go diff --git a/go.mod b/go.mod index cdfb09df..77ca8426 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/go-git/go-git/v5 v5.4.2 github.com/go-openapi/runtime v0.21.0 github.com/open-policy-agent/opa v0.37.0 + github.com/owenrumney/go-sarif v1.1.1 github.com/sigstore/rekor v0.4.0 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.3.0 @@ -19,7 +20,10 @@ require ( gopkg.in/square/go-jose.v2 v2.6.0 ) -require github.com/jmespath/go-jmespath v0.4.0 // indirect +require ( + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/zclconf/go-cty v1.10.0 // indirect +) require ( github.com/Microsoft/go-winio v0.5.1 // indirect diff --git a/go.sum b/go.sum index 3b23dfc0..991bfaad 100644 --- a/go.sum +++ b/go.sum @@ -199,6 +199,7 @@ github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -1269,6 +1270,8 @@ github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/owenrumney/go-sarif v1.1.1 h1:QNObu6YX1igyFKhdzd7vgzmw7XsWN3/6NMGuDzBgXmE= +github.com/owenrumney/go-sarif v1.1.1/go.mod h1:dNDiPlF04ESR/6fHlPyq7gHKmrM0sHUvAGjsoh8ZH0U= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1528,6 +1531,8 @@ github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:tw github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= @@ -1567,6 +1572,8 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zalando/go-keyring v0.1.0/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0= github.com/zalando/go-keyring v0.1.1/go.mod h1:OIC+OZ28XbmwFxU/Rp9V7eKzZjamBJwRzC8UFJH9+L8= +github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= +github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g= github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/pkg/attestation/sarif/sarif.go b/pkg/attestation/sarif/sarif.go new file mode 100644 index 00000000..c2d65670 --- /dev/null +++ b/pkg/attestation/sarif/sarif.go @@ -0,0 +1,119 @@ +// Copyright 2022 The Witness Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sarif + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/owenrumney/go-sarif/sarif" + "github.com/testifysec/witness/pkg/attestation" + "github.com/testifysec/witness/pkg/cryptoutil" +) + +const ( + Name = "sarif" + Type = "https://witness.testifysec.com/attestations/sarif/v0.1" + RunType = attestation.PostRunType +) + +var mimeTypes = []string{"text/plain", "application/json"} + +func init() { + attestation.RegisterAttestation(Name, Type, RunType, func() attestation.Attestor { + return New() + }) +} + +type Attestor struct { + sarif.Report `json:"report"` + ReportFile string `json:"reportFileName"` + ReportDigestSet cryptoutil.DigestSet `json:"reportDigestSet"` +} + +func New() *Attestor { + return &Attestor{} +} + +func (a *Attestor) Name() string { + return Name +} + +func (a *Attestor) Type() string { + return Type +} + +func (a *Attestor) RunType() attestation.RunType { + return RunType +} + +func (a *Attestor) Attest(ctx *attestation.AttestationContext) error { + if err := a.getCanidate(ctx); err != nil { + fmt.Printf("error getting canidate: %s\n", err) + return err + } + + return nil +} + +func (a *Attestor) getCanidate(ctx *attestation.AttestationContext) error { + products := ctx.Products() + + if len(products) == 0 { + return fmt.Errorf("no products to attest") + } + + for path, product := range products { + for _, mimeType := range mimeTypes { + if !strings.Contains(mimeType, product.MimeType) { + continue + } + } + + newDigestSet, err := cryptoutil.CalculateDigestSetFromFile(path, ctx.Hashes()) + if newDigestSet == nil || err != nil { + return fmt.Errorf("error calculating digest set from file: %s", path) + } + + if !newDigestSet.Equal(product.Digest) { + return fmt.Errorf("integrity error: product digest set does not match canidate digest set") + } + + f, err := os.Open(path) + if err != nil { + return fmt.Errorf("error opening file: %s", path) + } + + reportBytes, err := ioutil.ReadAll(f) + if err != nil { + return fmt.Errorf("error reading file: %s", path) + } + + //check to see if we can unmarshal into sarif type + if err := json.Unmarshal(reportBytes, &a.Report); err != nil { + fmt.Printf("error unmarshaling report: %s\n", err) + continue + } + + a.ReportFile = path + a.ReportDigestSet = product.Digest + + return nil + } + return fmt.Errorf("no sarif file found") +}