aboutsummaryrefslogtreecommitdiff
path: root/cvss/v31vector.go
diff options
context:
space:
mode:
Diffstat (limited to 'cvss/v31vector.go')
-rw-r--r--cvss/v31vector.go119
1 files changed, 119 insertions, 0 deletions
diff --git a/cvss/v31vector.go b/cvss/v31vector.go
new file mode 100644
index 0000000..f286ea0
--- /dev/null
+++ b/cvss/v31vector.go
@@ -0,0 +1,119 @@
+package cvss
+
+import (
+ "regexp"
+ "strings"
+)
+
+// CVSS v3.1 prefix
+var v31Prefix = "CVSS:3.1/"
+
+// CVSS 3.1 vector.
+type v31Vector []v3Metric
+
+// Convert vector to string
+func (v v31Vector) String() string {
+ // convert to slice of metrics
+ metrics := []v3Metric(v)
+
+ // build vector
+ r := make([]string, len(metrics))
+ for i, m := range(metrics) {
+ r[i] = m.String()
+ }
+
+ // build and return string
+ return v31Prefix + strings.Join(r, "/")
+}
+
+// Return CVSS version.
+func (v31Vector) Version() Version {
+ return V31
+}
+
+// Return metrics in this vector.
+func (v v31Vector) Metrics() []Metric {
+ // build slice of metrics
+ r := make([]Metric, len(v))
+ for i, m := range(v) {
+ r[i] = m
+ }
+
+ // return result
+ return r
+}
+
+// create CVSS 3.1 vector from string.
+func newV31Vector(s string) (v31Vector, error) {
+ // strip version prefix, split into metric strings
+ strs := strings.Split(s[len(v31Prefix):], "/")
+ r := make([]v3Metric, len(strs))
+
+ // build results
+ for i, ms := range(strs) {
+ // get metric from string
+ m, err := getV3Metric(V31, ms)
+ if err != nil {
+ return nil, err
+ }
+
+ // add to results
+ r[i] = m
+ }
+
+ // return result
+ return v31Vector(r), nil
+}
+
+// // Unmarshal CVSS 3.1 vector from JSON string.
+// func (me *v31Vector) UnmarshalJSON(b []byte) error {
+// // decode string, check for error
+// var s string
+// if err := json.Unmarshal(b, &s); err != nil {
+// return err
+// }
+//
+// // parse vector, check for error
+// r, err := newV31Vector(s)
+// if err != nil {
+// return err
+// }
+//
+// // save result, return success
+// *me = r
+// return nil
+// }
+
+var v31VecRe = regexp.MustCompile(
+ "\\ACVSS:3\\.1(?:/(?:" + strings.Join([]string {
+ "(?:AV:[NALP])",
+ "(?:AC:[LH])",
+ "(?:PR:[NLH])",
+ "(?:UI:[NR])",
+ "(?:S:[UC])",
+ "(?:C:[HLN])",
+ "(?:I:[HLN])",
+ "(?:A:[HLN])",
+ "(?:E:[XHFPU])",
+ "(?:RL:[XUWTO])",
+ "(?:RC:[XCRU])",
+ "(?:CR:[XHML])",
+ "(?:IR:[XHML])",
+ "(?:AR:[XHML])",
+ "(?:MAV:[XNALP])",
+ "(?:MAC:[XLH])",
+ "(?:MPR:[XNLH])",
+ "(?:MUI:[XNR])",
+ "(?:MS:[XUC])",
+ "(?:MC:[XNLH])",
+ "(?:MI:[XNLH])",
+ "(?:MA:[XNLH])",
+ }, "|") + "))+\\z",
+)
+
+// Is the given string a CVSSv3.1 vector string?
+func isV31VectorString(s string) bool {
+ return (len(s) > len(v31Prefix)) &&
+ (s[:len(v31Prefix)] == v31Prefix) &&
+ v31VecRe.MatchString(s)
+}