aboutsummaryrefslogtreecommitdiff
path: root/cvss/v30vector.go
diff options
context:
space:
mode:
Diffstat (limited to 'cvss/v30vector.go')
-rw-r--r--cvss/v30vector.go119
1 files changed, 119 insertions, 0 deletions
diff --git a/cvss/v30vector.go b/cvss/v30vector.go
new file mode 100644
index 0000000..5ef1ae8
--- /dev/null
+++ b/cvss/v30vector.go
@@ -0,0 +1,119 @@
+package cvss
+
+import (
+ // "encoding/json"
+ "regexp"
+ "strings"
+)
+
+// CVSS v3.0 prefix
+var v30Prefix = "CVSS:3.0/"
+
+// CVSS 3.0 vector.
+type v30Vector []v3Metric
+
+// Convert vector to string
+func (v v30Vector) 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 v30Prefix + strings.Join(r, "/")
+}
+
+// Return CVSS version.
+func (v30Vector) Version() Version {
+ return V30
+}
+
+// Return metrics in this vector.
+func (v v30Vector) Metrics() []Metric {
+ // build result
+ r := make([]Metric, len(v))
+ for i, m := range(v) {
+ r[i] = m
+ }
+
+ // return result
+ return r
+}
+
+// Create CVSS 3.0 vector from string.
+func newV30Vector(s string) (v30Vector, error) {
+ // strip version prefix, split into metric strings
+ strs := strings.Split(s[len(v30Prefix):], "/")
+ r := make([]v3Metric, len(strs))
+
+ // build results
+ for i, ms := range(strs) {
+ // get metric from string
+ m, err := getV3Metric(V30, ms)
+ if err != nil {
+ return nil, err
+ }
+
+ r[i] = m
+ }
+
+ // return result
+ return v30Vector(r), nil
+}
+
+// // Unmarshal CVSS 3.0 vector from JSON string.
+// func (me *v30Vector) 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 := newV30Vector(s)
+// if err != nil {
+// return err
+// }
+//
+// // save result, return success
+// *me = r
+// return nil
+// }
+
+var v30VecRe = regexp.MustCompile(
+ "\\ACVSS:3\\.0(?:/(?:" + 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 isV30VectorString(s string) bool {
+ return (len(s) > len(v30Prefix)) &&
+ (s[:len(v30Prefix)] == v30Prefix) &&
+ v30VecRe.MatchString(s)
+}