diff --git a/.golangci.yml b/.golangci.yml index e3308d5..594bca7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -21,7 +21,7 @@ linters: enable: - asciicheck - bodyclose - - depguard + # - depguard - dogsled - dupl - durationcheck diff --git a/go.mod b/go.mod index a1cfaae..63cb967 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,10 @@ module github.com/openvex/vexctl go 1.20 + +replace github.com/openvex/go-vex => /home/urbano/Projects/openvex/go-vex/ + + require ( github.com/google/go-containerregistry v0.15.2 github.com/in-toto/in-toto-golang v0.9.0 diff --git a/internal/cmd/create.go b/internal/cmd/create.go index af45b2c..42bb3c6 100644 --- a/internal/cmd/create.go +++ b/internal/cmd/create.go @@ -27,8 +27,8 @@ func (o *createOptions) Validate(args []string) error { if o.Status != string(vex.StatusAffected) && o.ActionStatement == vex.NoActionStatementMsg { o.ActionStatement = "" } - if len(args) == 0 && len(o.Products) == 0 { - return errors.New("a required product id is required to generate a valid VEX statement") + if o.Product == "" { + return errors.New("a required product id is needed to generate a valid VEX statement") } if len(args) < 2 && o.Vulnerability == "" { @@ -105,7 +105,7 @@ Examples: for i := range args { switch i { case 0: - opts.Products = append(opts.Products, args[i]) + opts.Product = args[i] case 1: opts.Vulnerability = args[i] case 2: @@ -127,9 +127,19 @@ Examples: } statement := vex.Statement{ - Vulnerability: opts.Vulnerability, - Products: opts.Products, - Subcomponents: opts.Subcomponents, + Vulnerability: vex.Vulnerability{ + Name: vex.VulnerabilityID(opts.Vulnerability), + }, + Products: []vex.Product{ + { + Component: vex.Component{ + ID: opts.Product, + Hashes: map[vex.Algorithm]vex.Hash{}, + Identifiers: map[vex.IdentifierType]string{}, + }, + Subcomponents: []vex.Subcomponent{}, + }, + }, Status: vex.Status(opts.Status), StatusNotes: opts.StatusNotes, Justification: vex.Justification(opts.Justification), @@ -137,6 +147,12 @@ Examples: ActionStatement: opts.ActionStatement, } + for _, sc := range opts.Subcomponents { + statement.Products[0].Subcomponents = append(statement.Products[0].Subcomponents, vex.Subcomponent{ + Component: vex.Component{ID: sc}, + }) + } + if err := statement.Validate(); err != nil { return fmt.Errorf("invalid statement: %w", err) } @@ -197,11 +213,11 @@ Examples: "vulnerability to add to the statement (eg CVE-2023-12345)", ) - createCmd.PersistentFlags().StringSliceVarP( - &opts.Products, + createCmd.PersistentFlags().StringVarP( + &opts.Product, "product", "p", - []string{}, + "", "list of products to list in the statement, at least one is required", ) diff --git a/internal/cmd/main.go b/internal/cmd/main.go index 7699aea..2adfa02 100644 --- a/internal/cmd/main.go +++ b/internal/cmd/main.go @@ -69,7 +69,7 @@ type vexStatementOptions struct { ImpactStatement string Vulnerability string ActionStatement string - Products []string + Product string Subcomponents []string } diff --git a/pkg/ctl/implementation.go b/pkg/ctl/implementation.go index 24cc832..b48c3fb 100644 --- a/pkg/ctl/implementation.go +++ b/pkg/ctl/implementation.go @@ -354,15 +354,16 @@ func (impl *defaultVexCtlImplementation) Merge( LOOP_STATEMENTS: for _, s := range doc.Statements { //nolint:gocritic // this IS supposed to copy if len(iProds) > 0 { - for _, pid := range s.Products { - if _, ok := iProds[pid]; !ok { + for _, product := range s.Products { + if _, ok := iProds[product.ID]; !ok { continue LOOP_STATEMENTS } } } if len(iVulns) > 0 { - if _, ok := iProds[s.Vulnerability]; !ok { + // FIXME: This is wrong + if _, ok := iProds[s.Vulnerability.ID]; !ok { continue LOOP_STATEMENTS } } @@ -413,7 +414,7 @@ func (impl *defaultVexCtlImplementation) ListDocumentProducts(doc *vex.VEX) ([]s products := []string{} for i := range doc.Statements { for _, p := range doc.Statements[i].Products { - inv[p] = struct{}{} + inv[p.ID] = struct{}{} } } for p := range inv { diff --git a/pkg/ctl/implementation_test.go b/pkg/ctl/implementation_test.go index e4c99bc..e4ab0de 100644 --- a/pkg/ctl/implementation_test.go +++ b/pkg/ctl/implementation_test.go @@ -155,7 +155,18 @@ func TestVerifyImageSubjects(t *testing.T) { doc := vex.New() for _, p := range tc.products { doc.Statements = append( - doc.Statements, vex.Statement{Products: []string{p}}, + doc.Statements, vex.Statement{ + Products: []vex.Product{ + { + Component: vex.Component{ + ID: p, + Hashes: map[vex.Algorithm]vex.Hash{}, + Identifiers: map[vex.IdentifierType]string{}, + }, + Subcomponents: []vex.Subcomponent{}, + }, + }, + }, ) } err := impl.VerifyImageSubjects(att, &doc)