aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/cvss.go33
-rw-r--r--cvss/calc.go80
2 files changed, 113 insertions, 0 deletions
diff --git a/cmd/cvss.go b/cmd/cvss.go
new file mode 100644
index 0000000..d704811
--- /dev/null
+++ b/cmd/cvss.go
@@ -0,0 +1,33 @@
+package cmd
+
+import (
+ "encoding/json"
+ "github.com/pablotron/cvez/cvss"
+ "github.com/spf13/cobra"
+ "github.com/rs/zerolog"
+ "github.com/rs/zerolog/log"
+ "os"
+ "time"
+)
+
+var cvssCmd = &cobra.Command{
+ Use: "cvss",
+ Short: "CVSS vector calculator.",
+ Long: `Common Vulnerability Scoring System (CVSS) vector calculator.`,
+
+ Run: func(cmd *cobra.Command, args []string) {
+ // set global logging options
+ zerolog.TimeFieldFormat = time.RFC3339
+ zerolog.SetGlobalLevel(zerolog.InfoLevel)
+
+ // parse args, write result
+ e := json.NewEncoder(os.Stdout)
+ if err := e.Encode(cvss.Calc(args)); err != nil {
+ log.Error().Err(err).Msg("Encode")
+ }
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(cvssCmd)
+}
diff --git a/cvss/calc.go b/cvss/calc.go
new file mode 100644
index 0000000..7f22249
--- /dev/null
+++ b/cvss/calc.go
@@ -0,0 +1,80 @@
+package cvss
+
+// Calculated scores
+type CalcScores struct {
+ Base float32 `json:"base,omitempty"`
+ Temporal float32 `json:"temp,omitempty"`
+ Env float32 `json:"env,omitempty"`
+}
+
+// Calculated severities
+type CalcSeverities struct {
+ Base string `json:"base,omitempty"`
+ Temporal string `json:"temp,omitempty"`
+ Env string `json:"env,omitempty"`
+}
+
+// Row returned by Calc().
+type CalcRow struct {
+ // Input string
+ String string `json:"string"`
+
+ // vector error
+ Error string `json:"error,omitempty"`
+
+ // CVSS version
+ Version string `json:"version,omitempty"`
+
+ // CVSS scores
+ Scores CalcScores `json:"scores,omitempty"`
+
+ // severities
+ Severities CalcSeverities `json:"severities,omitempty"`
+}
+
+// Parse CVSS vector strings and extract the relevant attributes.
+func Calc(args []string) []CalcRow {
+ rows := make([]CalcRow, len(args))
+
+ for i, s := range(args) {
+ // parse vector
+ if vec, err := NewVector(s); err != nil {
+ // parse failed
+ rows[i] = CalcRow {
+ String: s,
+ Error: err.Error(),
+ }
+ } else {
+ // parse scores
+ if scores, err := vec.Scores(); err != nil {
+ // parse scores failed
+ rows[i] = CalcRow {
+ String: s,
+ Error: err.Error(),
+ Version: vec.Version().String(),
+ }
+ } else {
+ // parse scores succeeded, add to results
+ rows[i] = CalcRow {
+ String: s,
+ Version: vec.Version().String(),
+
+ Scores: CalcScores {
+ Base: scores.Base.Float(),
+ Temporal: scores.Temporal.Float(),
+ Env: scores.Env.Float(),
+ },
+
+ Severities: CalcSeverities {
+ Base: scores.Base.Severity().String(),
+ Temporal: scores.Temporal.Severity().String(),
+ Env: scores.Env.Severity().String(),
+ },
+ }
+ }
+ }
+ }
+
+ // return results
+ return rows
+}