// CVSS vector parser. package cvss import ( "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) (Vector, error) { strs := strings.Split(s, "/") r := make([]v3Metric, len(strs)) // walk metric strings for i, ms := range(strs) { // convert metric string to metric m, err := getV3Metric(V30, ms) if err != nil { return nil, err } // add to results r[i] = m } // build and return vector return v30Vector(r), nil } // 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 result 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) (Vector, error) { strs := strings.Split(s, "/") r := make([]v3Metric, len(strs)) // walk metric strings 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 } // build and return vector return v31Vector(r), nil } // Metric key. type Key interface { // Get full name. Name() string // Get category. Category() Category // Return string representation. String() string } // CVSS metric. type Metric interface { // Get metric key. Key() Key // Return string representation of metric. String() string } // CVSS metric vector. type Vector interface { // Get CVSS version. Version() Version // Get CVSS vector string. String() string // Return metrics in this vector. Metrics() []Metric } // Create new CVSS vector from vector string. func NewVector(s string) (Vector, error) { if len(s) > len(v31Prefix) && s[:len(v31Prefix)] == v31Prefix { // create CVSS v2.0 vector. return newV31Vector(s[len(v31Prefix):]) } else if len(s) > len(v30Prefix) && s[:len(v30Prefix)] == v30Prefix { // create CVSS v3.0 vector. return newV30Vector(s[len(v30Prefix):]) } else { // create CVSS V2 vector return newV2Vector(s) } }