Skip to content
This repository has been archived by the owner on Mar 27, 2023. It is now read-only.

Commit

Permalink
Update vexctl create to latest spec
Browse files Browse the repository at this point in the history
This commit modifies vexctl create to comply with the las changes of
the data model decided by the vex group on jan 9th 2022. The command
will now require an action statement with the flag --action-statement
and add a defult if its not set.

Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]>
  • Loading branch information
puerco committed Jan 10, 2023
1 parent d0b015a commit 102a882
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 28 deletions.
44 changes: 17 additions & 27 deletions internal/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type createOptions struct {

// Validates the options in context with arguments
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")
}
Expand All @@ -43,33 +46,6 @@ func (o *createOptions) Validate(args []string) error {
return errors.New("status can only be specified once")
}

statusString := o.Status
if statusString == "" {
if len(args) < 3 {
return fmt.Errorf("a valid status is required to generate a valid VEX statement")
}
statusString = args[2]
}
status := vex.Status(statusString)
if !status.Valid() {
return fmt.Errorf(
"invalid VEX impact status '%s', valid status are: %s",
status, strings.Join(vex.Statuses(), ", "),
)
}

if status == vex.StatusNotAffected {
if o.Justification == "" {
return fmt.Errorf("an '%s' statement requires a valid justification: [%s]", vex.StatusAffected, strings.Join(vex.Justifications(), ", "))
}

if !vex.Justification(o.Justification).Valid() {
return fmt.Errorf("%s is not a valid VEX justification, valid justifications: %s", vex.StatusAffected, strings.Join(vex.Justifications(), ", "))
}
} else if o.Justification != "" {
return fmt.Errorf("a %s impact status must not have a justification", status)
}

return nil
}

Expand Down Expand Up @@ -145,7 +121,13 @@ Examples:
StatusNotes: opts.StatusNotes,
Justification: vex.Justification(opts.Justification),
ImpactStatement: opts.ImpactStatement,
ActionStatement: opts.ActionStatement,
}

if err := statement.Validate(); err != nil {
return fmt.Errorf("invalid statement: %w", err)
}

newDoc.Statements = append(newDoc.Statements, statement)
if _, err := newDoc.GenerateCanonicalID(); err != nil {
return fmt.Errorf("generating document id: %w", err)
Expand Down Expand Up @@ -233,6 +215,14 @@ Examples:
fmt.Sprintf("justification for not_affected status, see '%s show justifications' for list", appname),
)

createCmd.PersistentFlags().StringVarP(
&opts.ActionStatement,
"action-statement",
"a",
vex.NoActionStatementMsg,
"action statement for affected status",
)

createCmd.PersistentFlags().StringVar(
&opts.outFilePath,
"file",
Expand Down
1 change: 1 addition & 0 deletions internal/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type vexStatementOptions struct {
Justification string
ImpactStatement string
Vulnerability string
ActionStatement string
Products []string
Subcomponents []string
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/vex/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type Statement struct {
// that contains a description why the vulnerability cannot be exploited.
ImpactStatement string `json:"impact_statement,omitempty"`

// For "affected" status, a VEX statement MAY include an ActionStatement that
// For "affected" status, a VEX statement MUST include an ActionStatement that
// SHOULD describe actions to remediate or mitigate [vul_id].
ActionStatement string `json:"action_statement,omitempty"`
ActionStatementTimestamp *time.Time `json:"action_statement_timestamp,omitempty"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/vex/vex.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ const (

// PublicNamespace is the public openvex namespace for common @ids
PublicNamespace = "https://openvex.dev/docs"

// NoActionStatementMsg is the action statement that informs that there is no action statement :/
NoActionStatementMsg = "No action statement provided"
)

// The VEX type represents a VEX document and all of its contained information.
Expand Down

0 comments on commit 102a882

Please sign in to comment.