From b3dc36421f133ea6983574891720e974cf7974dd Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Mon, 31 Jan 2022 11:09:58 -0500 Subject: initial commit --- internal/cvss/cvss.go | 926 +++++++++++++++++++++++++++++++++ internal/cvss/metriccategory_string.go | 25 + internal/cvss/v2metric_string.go | 77 +++ internal/cvss/v2metrickey_string.go | 36 ++ internal/cvss/v3metric_string.go | 100 ++++ internal/cvss/v3metrickey_string.go | 44 ++ internal/cvss/version_string.go | 25 + 7 files changed, 1233 insertions(+) create mode 100644 internal/cvss/cvss.go create mode 100644 internal/cvss/metriccategory_string.go create mode 100644 internal/cvss/v2metric_string.go create mode 100644 internal/cvss/v2metrickey_string.go create mode 100644 internal/cvss/v3metric_string.go create mode 100644 internal/cvss/v3metrickey_string.go create mode 100644 internal/cvss/version_string.go (limited to 'internal/cvss') diff --git a/internal/cvss/cvss.go b/internal/cvss/cvss.go new file mode 100644 index 0000000..e50f718 --- /dev/null +++ b/internal/cvss/cvss.go @@ -0,0 +1,926 @@ +// CVSS vector parser. +package cvss + +import ( + "fmt" + "strings" +) + +//go:generate stringer -linecomment -type=Version +//go:generate stringer -linecomment -type=MetricCategory +//go:generate stringer -linecomment -type=V2MetricKey +//go:generate stringer -linecomment -type=V2Metric +//go:generate stringer -linecomment -type=V3MetricKey +//go:generate stringer -linecomment -type=V3Metric + +// CVSS version +type Version byte + +const ( + V20 Version = iota // 2.0 + V30 // 3.0 + V31 // 3.1 +) + +// CVSS metric category. +type MetricCategory byte + +const ( + Base MetricCategory = iota // Base + Temporal // Temporal + Environmental // Environmental +) + +// CVSS metric key +type V2MetricKey byte + +const ( + V2AccessVector V2MetricKey = iota // AV + V2AccessComplexity // AC + V2Authentication // Au + V2ConfidentialityImpact // C + V2IntegrityImpact // I + V2AvailabilityImpact // A + V2Exploitability // E + V2RemediationLevel // RL + V2ReportConfidence // RC + V2CollateralDamagePotential // CDP + V2TargetDistribution // TD + V2ConfidentialityRequirement // CR + V2IntegrityRequirement // IR + V2AvailabilityRequirement // AR +) + +// CVSS V2 metric key info lut +var v2MetricKeys = map[V2MetricKey]struct { + Name string + Category MetricCategory +} { + V2AccessVector: { "Access Vector", Base }, + V2AccessComplexity: { "Access Complexity", Base }, + V2Authentication: { "Authentication", Base }, + V2ConfidentialityImpact: { "Confidentiality Impact", Base }, + V2IntegrityImpact: { "Integrity Impact", Base }, + V2AvailabilityImpact: { "Availability Impact", Base }, + V2Exploitability: { "Exploitability", Temporal }, + V2RemediationLevel: { "Remediation Level", Temporal }, + V2ReportConfidence: { "Report Confidence", Temporal }, + V2CollateralDamagePotential: { "Collateral Damage Potential", Environmental }, + V2TargetDistribution: { "Target Distribution", Environmental }, + V2ConfidentialityRequirement: { "Confidentiality Requirement", Environmental }, + V2IntegrityRequirement: { "Integrity Requirement", Environmental }, + V2AvailabilityRequirement: { "Availability Requirement", Environmental }, +} + +// v2 metric key IDs lut +var v2MetricKeyIds = map[string]V2MetricKey { + "AV": V2AccessVector, + "AC": V2AccessComplexity, + "Au": V2Authentication, + "C": V2ConfidentialityImpact, + "I": V2IntegrityImpact, + "A": V2AvailabilityImpact, + "E": V2Exploitability, + "RL": V2RemediationLevel, + "RC": V2ReportConfidence, + "CDP": V2CollateralDamagePotential, + "TD": V2TargetDistribution, + "CR": V2ConfidentialityRequirement, + "IR": V2IntegrityRequirement, + "AR": V2AvailabilityRequirement, +} + +// Get metric key from string. +func GetV2MetricKeyFromString(s string) (V2MetricKey, error) { + k, ok := v2MetricKeyIds[s] + if ok { + return k, nil + } else { + return V2AccessVector, fmt.Errorf("unknown metric key: %s", s) + } +} + +// Get metric key name. +func (k V2MetricKey) Name() string { + return v2MetricKeys[k].Name +} + +// Get metric key category. +func (k V2MetricKey) Category() MetricCategory { + return v2MetricKeys[k].Category +} + +// CVSS v2 metric value +type V2Metric byte + +const ( + V2AVNetwork V2Metric = iota // AV:N + V2AVAdjacentNetwork // AV:A + V2AVLocal // AV:L + + V2ACLow // AC:L + V2ACMedium // AC:L + V2ACHigh // AC:H + + V2AuMultiple // Au:M + V2AuSingle // Au:S + V2AuNone // Au:N + + V2CNone // C:N + V2CPartial // C:P + V2CComplete // C:C + + V2INone // I:N + V2IPartial // I:P + V2IComplete // I:C + + V2ANone // A:N + V2APartial // A:P + V2AComplete // A:C + + V2ENotDefined // E:ND + V2EUnproven // E:U + V2EProofOfConcept // E:POC + V2EFunctional // E:F + V2EHigh // E:H + + V2RLOfficialFix // RL:OF + V2RLTemporaryFix // RL:TF + V2RLWorkaround // RL:W + V2RLUnavailable // RL:U + V2RLNotDefined // RL:ND + + V2RCUnconfirmed // RC:UC + V2RCUncorroborated // RC:UR + V2RCConfirmed // RC:C + V2RCNotDefined // RC:ND + + V2CDPNone // CDP:N + V2CDPLow // CDP:L + V2CDPLowMedium // CDP:LM + V2CDPMediumHigh // CDP:MH + V2CDPHigh // CDP:H + V2CDPNotDefined // CDP:ND + + V2TDNone // TD:N + V2TDLow // TD:L + V2TDMedium // TD:M + V2TDHigh // TD:H + V2TDNotDefined // TD:ND + + V2CRLow // CR:L + V2CRMedium // CR:M + V2CRHigh // CR:H + V2CRNotDefined // CR:ND + + V2IRLow // IR:L + V2IRMedium // IR:M + V2IRHigh // IR:H + V2IRNotDefined // IR:ND + + V2ARLow // AR:L + V2ARMedium // AR:M + V2ARHigh // AR:H + V2ARNotDefined // AR:ND +) + +// map of metrics to metric keys +var v2MetricKeyLut = map[V2Metric]V2MetricKey { + V2AVNetwork: V2AccessVector, + V2AVAdjacentNetwork: V2AccessVector, + V2AVLocal: V2AccessVector, + + V2ACLow: V2AccessComplexity, + V2ACMedium: V2AccessComplexity, + V2ACHigh: V2AccessComplexity, + + V2AuMultiple: V2Authentication, + V2AuSingle: V2Authentication, + V2AuNone: V2Authentication, + + V2CNone: V2ConfidentialityImpact, + V2CPartial: V2ConfidentialityImpact, + V2CComplete: V2ConfidentialityImpact, + + V2INone: V2IntegrityImpact, + V2IPartial: V2IntegrityImpact, + V2IComplete: V2IntegrityImpact, + + V2ANone: V2AvailabilityImpact, + V2APartial: V2AvailabilityImpact, + V2AComplete: V2AvailabilityImpact, + + V2ENotDefined: V2Exploitability, + V2EUnproven: V2Exploitability, + V2EProofOfConcept: V2Exploitability, + V2EFunctional: V2Exploitability, + V2EHigh: V2Exploitability, + + V2RLOfficialFix: V2RemediationLevel, + V2RLTemporaryFix: V2RemediationLevel, + V2RLWorkaround: V2RemediationLevel, + V2RLUnavailable: V2RemediationLevel, + V2RLNotDefined: V2RemediationLevel, + + V2RCUnconfirmed: V2ReportConfidence, + V2RCUncorroborated: V2ReportConfidence, + V2RCConfirmed: V2ReportConfidence, + V2RCNotDefined: V2ReportConfidence, + + V2CDPNone: V2CollateralDamagePotential, + V2CDPLow: V2CollateralDamagePotential, + V2CDPLowMedium: V2CollateralDamagePotential, + V2CDPMediumHigh: V2CollateralDamagePotential, + V2CDPHigh: V2CollateralDamagePotential, + V2CDPNotDefined: V2CollateralDamagePotential, + + V2TDNone: V2TargetDistribution, + V2TDLow: V2TargetDistribution, + V2TDMedium: V2TargetDistribution, + V2TDHigh: V2TargetDistribution, + V2TDNotDefined: V2TargetDistribution, + + V2CRLow: V2ConfidentialityRequirement, + V2CRMedium: V2ConfidentialityRequirement, + V2CRHigh: V2ConfidentialityRequirement, + V2CRNotDefined: V2ConfidentialityRequirement, + + V2IRLow: V2IntegrityRequirement, + V2IRMedium: V2IntegrityRequirement, + V2IRHigh: V2IntegrityRequirement, + V2IRNotDefined: V2IntegrityRequirement, + + V2ARLow: V2AvailabilityRequirement, + V2ARMedium: V2AvailabilityRequirement, + V2ARHigh: V2AvailabilityRequirement, + V2ARNotDefined: V2AvailabilityRequirement, +} + +// map of metric strings to metrics +var v2MetricStrLut = map[string]V2Metric { + "AV:N": V2AVNetwork, + "AV:A": V2AVAdjacentNetwork, + "AV:L": V2AVLocal, + + "AC:L": V2ACLow, + "AC:M": V2ACMedium, + "AC:H": V2ACHigh, + + "Au:M": V2AuMultiple, + "Au:S": V2AuSingle, + "Au:N": V2AuNone, + + "C:N": V2CNone, + "C:P": V2CPartial, + "C:C": V2CComplete, + + "I:N": V2INone, + "I:P": V2IPartial, + "I:C": V2IComplete, + + "A:N": V2ANone, + "A:P": V2APartial, + "A:C": V2AComplete, + + "E:ND": V2ENotDefined, + "E:U": V2EUnproven, + "E:POC": V2EProofOfConcept, + "E:F": V2EFunctional, + "E:H": V2EHigh, + + "RL:OF": V2RLOfficialFix, + "RL:TF": V2RLTemporaryFix, + "RL:W": V2RLWorkaround, + "RL:U": V2RLUnavailable, + "RL:ND": V2RLNotDefined, + + "RC:UC": V2RCUnconfirmed, + "RC:UR": V2RCUncorroborated, + "RC:C": V2RCConfirmed, + "RC:ND": V2RCNotDefined, + + "CDP:N": V2CDPNone, + "CDP:L": V2CDPLow, + "CDP:LM": V2CDPLowMedium, + "CDP:MH": V2CDPMediumHigh, + "CDP:H": V2CDPHigh, + "CDP:ND": V2CDPNotDefined, + + "TD:N": V2TDNone, + "TD:L": V2TDLow, + "TD:M": V2TDMedium, + "TD:H": V2TDHigh, + "TD:ND": V2TDNotDefined, + + "CR:L": V2CRLow, + "CR:M": V2CRMedium, + "CR:H": V2CRHigh, + "CR:ND": V2CRNotDefined, + + "IR:L": V2IRLow, + "IR:M": V2IRMedium, + "IR:H": V2IRHigh, + "IR:ND": V2IRNotDefined, + + "AR:L": V2ARLow, + "AR:M": V2ARMedium, + "AR:H": V2ARHigh, + "AR:ND": V2ARNotDefined, +} + +// Convert string to CVSS 2.0 metric. +func GetV2MetricFromString(s string) (V2Metric, error) { + // get metric + m, ok := v2MetricStrLut[s] + if !ok { + return V2AVNetwork, fmt.Errorf("invalid metric: %s", s) + } + + // return success + return m, nil +} + +// CVSS 2.0 vector. +type v2Vector []V2Metric + +// Convert vector to string +func (v v2Vector) String() string { + // convert to slice of metrics + metrics := []V2Metric(v) + + // build vector + r := make([]string, len(metrics)) + for i, m := range(metrics) { + r[i] = m.String() + } + + // build and return string + return strings.Join(r, "/") +} + +// Return CVSS version. +func (v2Vector) Version() Version { + return V20 +} + +// create CVSS 2.0 vector from string +func NewV2VectorFromString(s string) (Vector, error) { + strs := strings.Split(s, "/") + r := make([]V2Metric, len(strs)) + + // walk metric strings + for i, ms := range(strs) { + // convert string to vector + m, err := GetV2MetricFromString(ms) + if err != nil { + return nil, err + } + + // add to results + r[i] = m + } + + // build and return vector + return v2Vector(r), nil +} + +// CVSS v3 metric key +type V3MetricKey byte + +const ( + V3AttackVector V3MetricKey = iota // AV + V3AttackComplexity // AC + V3PrivilegesRequired // PR + V3UserInteraction // UI + V3Scope // S + V3Confidentiality // C + V3Integrity // I + V3Availability // A + V3ExploitCodeMaturity // E + V3RemediationLevel // RL + V3ReportConfidence // RC + V3ConfidentialityRequirement // CR + V3IntegrityRequirement // IR + V3AvailabilityRequirement // AR + V3ModifiedAttackVector // MAV + V3ModifiedAttackComplexity // MAC + V3ModifiedPrivilegesRequired // MPR + V3ModifiedUserInteraction // MUI + V3ModifiedScope // MS + V3ModifiedConfidentiality // MC + V3ModifiedIntegrity // MI + V3ModifiedAvailability // MA +) + +// CVSS V3 metric key info lut +var v3MetricKeys = map[V3MetricKey]struct { + Name string + Category MetricCategory +} { + V3AttackVector: { "Attack Vector", Base }, + V3AttackComplexity: { "Attack Complexity", Base }, + V3PrivilegesRequired: { "Privileges Required", Base }, + V3UserInteraction: { "User Interaction", Base }, + V3Scope: { "Scope", Base }, + V3Confidentiality: { "Confidentiality", Base }, + V3Integrity: { "Integrity", Base }, + V3Availability: { "Availability", Base }, + V3ExploitCodeMaturity: { "Exploit Code Maturity", Temporal }, + V3RemediationLevel: { "Remediation Level", Temporal }, + V3ReportConfidence: { "Report Confidence", Temporal }, + V3ConfidentialityRequirement: { "Confidentiality Requirement", Environmental }, + V3IntegrityRequirement: { "Integrity Requirement", Environmental }, + V3AvailabilityRequirement: { "Availability Requirement", Environmental }, + V3ModifiedAttackVector: { "Modified Attack Vector", Environmental }, + V3ModifiedAttackComplexity: { "Modified Attack Complexity", Environmental }, + V3ModifiedPrivilegesRequired: { "Modified Privileges Required", Environmental }, + V3ModifiedUserInteraction: { "Modified User Interaction", Environmental }, + V3ModifiedScope: { "Modified Scope", Environmental }, + V3ModifiedConfidentiality: { "Modified Confidentiality", Environmental }, + V3ModifiedIntegrity: { "Modified Integrity", Environmental }, + V3ModifiedAvailability: { "Modified Availability", Environmental }, +} + +// metric key IDs lut +var v3MetricKeyIds = map[string]V3MetricKey { + "AV": V3AttackVector, + "AC": V3AttackComplexity, + "PR": V3PrivilegesRequired, + "UI": V3UserInteraction, + "S": V3Scope, + "C": V3Confidentiality, + "I": V3Integrity, + "A": V3Availability, + "E": V3ExploitCodeMaturity, + "RL": V3RemediationLevel, + "RC": V3ReportConfidence, + "CR": V3ConfidentialityRequirement, + "IR": V3IntegrityRequirement, + "AR": V3AvailabilityRequirement, + "MAV": V3ModifiedAttackVector, + "MAC": V3ModifiedAttackComplexity, + "MPR": V3ModifiedPrivilegesRequired, + "MUI": V3ModifiedUserInteraction, + "MS": V3ModifiedScope, + "MC": V3ModifiedConfidentiality, + "MI": V3ModifiedIntegrity, + "MA": V3ModifiedAvailability, +} + +// Get metric key from string. +func GetV3MetricKeyFromString(s string) (V3MetricKey, error) { + k, ok := v3MetricKeyIds[s] + if ok { + return k, nil + } else { + return V3AttackVector, fmt.Errorf("unknown metric key: %s", s) + } +} + +// Get metric key name. +func (k V3MetricKey) Name() string { + return v3MetricKeys[k].Name +} + +// Get metric key category. +func (k V3MetricKey) Category() MetricCategory { + return v3MetricKeys[k].Category +} + +// metric value +type V3Metric byte + +const ( + V3AVNetwork V3Metric = iota // AV:N + V3AVAdjacentNetwork // AV:A + V3AVLocal // AV:L + V3AVPhysical // AV:P + + V3ACLow // AC:L + V3ACHigh // AC:H + + V3PRNone // PR:N + V3PRLow // PR:L + V3PRHigh // PR:H + + V3UINone // UI:N + V3UIRequired // UI:R + + V3SUnchanged // S:U + V3SChanged // S:C + + V3CHigh // C:H + V3CLow // C:L + V3CNone // C:N + + V3IHigh // I:H + V3ILow // I:L + V3INone // I:N + + V3AHigh // A:H + V3ALow // A:L + V3ANone // A:N + + V3ENotDefined // E:X + V3EHigh // E:H + V3EFunctional // E:F + V3EProofOfConcept // E:P + V3EUnproven // E:U + + V3RLNotDefined // RL:X + V3RLUnavailable // RL:U + V3RLWorkaround // RL:W + V3RLTemporaryFix // RL:T + V3RLOfficialFix // RL:O + + V3RCNotDefined // RC:X + V3RCConfirmed // RC:C + V3RCReasonable // RC:R + V3RCUnknown // RC:U + + V3CRNotDefined // CR:X + V3CRHigh // CR:H + V3CRMedium // CR:M + V3CRLow // CR:L + + V3IRNotDefined // IR:X + V3IRHigh // IR:H + V3IRMedium // IR:M + V3IRLow // IR:L + + V3ARNotDefined // AR:X + V3ARHigh // AR:H + V3ARMedium // AR:M + V3ARLow // AR:L + + V3MAVNotDefined // MAV:X + V3MAVNetwork // MAV:N + V3MAVAdjacentNetwork // MAV:A + V3MAVLocal // MAV:L + V3MAVPhysical // MAV:P + + V3MACNotDefined // MAC:X + V3MACLow // MAC:L + V3MACHigh // MAC:H + + V3MMRNotDefined // MPR:X + V3MPRLow // MPR:L + V3MPRHigh // MPR:H + + V3MUINotDefined // MUI:X + V3MUINone // MUI:N + V3MUIRequired // MUI:R + + V3MSNotDefined // MMS:X + V3MSUnchanged // MMS:U + V3MSChanged // MMS:C + + V3MCNotDefined // MC:X + V3MCHigh // MC:H + V3MCLow // MC:L + V3MCNone // MC:N + + V3MINotDefined // MI:X + V3MIHigh // MI:H + V3MILow // MI:L + V3MINone // MI:N + + V3MANotDefined // MA:X + V3MAHigh // MA:H + V3MALow // MA:L + V3MANone // MA:N + V3UnknownMetric // unknown +) + +// map of metrics to metric keys +var v3MetricKeyLut = map[V3Metric]V3MetricKey { + V3AVNetwork: V3AttackVector, // AV:N + V3AVAdjacentNetwork: V3AttackVector, // AV:A + V3AVLocal: V3AttackVector, // AV:L + V3AVPhysical: V3AttackVector, // AV:P + + V3ACLow: V3AttackComplexity, // AC:L + V3ACHigh: V3AttackComplexity, // AC:H + + V3PRNone: V3PrivilegesRequired, // PR:N + V3PRLow: V3PrivilegesRequired, // PR:L + V3PRHigh: V3PrivilegesRequired, // PR:H + + V3UINone: V3UserInteraction, // UI:N + V3UIRequired: V3UserInteraction, // UI:R + + V3SUnchanged: V3Scope, // S:U + V3SChanged: V3Scope, // S:C + + V3CHigh: V3Confidentiality, // C:H + V3CLow: V3Confidentiality, // C:L + V3CNone: V3Confidentiality, // C:N + + V3IHigh: V3Integrity, // I:H + V3ILow: V3Integrity, // I:L + V3INone: V3Integrity, // I:N + + V3AHigh: V3Availability, // A:H + V3ALow: V3Availability, // A:L + V3ANone: V3Availability, // A:N + + V3ENotDefined: V3ExploitCodeMaturity, // E:X + V3EHigh: V3ExploitCodeMaturity, // E:H + V3EFunctional: V3ExploitCodeMaturity, // E:F + V3EProofOfConcept: V3ExploitCodeMaturity, // E:P + V3EUnproven: V3ExploitCodeMaturity, // E:U + + V3RLNotDefined: V3RemediationLevel, // RL:X + V3RLUnavailable: V3RemediationLevel, // RL:U + V3RLWorkaround: V3RemediationLevel, // RL:W + V3RLTemporaryFix: V3RemediationLevel, // RL:T + V3RLOfficialFix: V3RemediationLevel, // RL:O + + V3RCNotDefined: V3ReportConfidence, // RC:X + V3RCConfirmed: V3ReportConfidence, // RC:C + V3RCReasonable: V3ReportConfidence, // RC:R + V3RCUnknown: V3ReportConfidence, // RC:U + + V3CRNotDefined: V3ConfidentialityRequirement, // CR:X + V3CRHigh: V3ConfidentialityRequirement, // CR:H + V3CRMedium: V3ConfidentialityRequirement, // CR:M + V3CRLow: V3ConfidentialityRequirement, // CR:L + + V3IRNotDefined: V3IntegrityRequirement, // IR:X + V3IRHigh: V3IntegrityRequirement, // IR:H + V3IRMedium: V3IntegrityRequirement, // IR:M + V3IRLow: V3IntegrityRequirement, // IR:L + + V3ARNotDefined: V3AvailabilityRequirement, // AR:X + V3ARHigh: V3AvailabilityRequirement, // AR:H + V3ARMedium: V3AvailabilityRequirement, // AR:M + V3ARLow: V3AvailabilityRequirement, // AR:L + + V3MAVNotDefined: V3ModifiedAttackVector, // MAV:X + V3MAVNetwork: V3ModifiedAttackVector, // MAV:N + V3MAVAdjacentNetwork: V3ModifiedAttackVector, // MAV:A + V3MAVLocal: V3ModifiedAttackVector, // MAV:L + V3MAVPhysical: V3ModifiedAttackVector, // MAV:P + + V3MACNotDefined: V3ModifiedAttackComplexity, // MAC:X + V3MACLow: V3ModifiedAttackComplexity, // MAC:L + V3MACHigh: V3ModifiedAttackComplexity, // MAC:H + + V3MMRNotDefined: V3ModifiedPrivilegesRequired, // MPR:X + V3MPRLow: V3ModifiedPrivilegesRequired, // MPR:L + V3MPRHigh: V3ModifiedPrivilegesRequired, // MPR:H + + V3MUINotDefined: V3ModifiedUserInteraction, // MUI:X + V3MUINone: V3ModifiedUserInteraction, // MUI:N + V3MUIRequired: V3ModifiedUserInteraction, // MUI:R + + V3MSNotDefined: V3ModifiedScope, // MMS:X + V3MSUnchanged: V3ModifiedConfidentiality, // MMS:U + V3MSChanged: V3ModifiedIntegrity, // MMS:C + + V3MCNotDefined: V3ModifiedConfidentiality, // MC:X + V3MCHigh: V3ModifiedConfidentiality, // MC:H + V3MCLow: V3ModifiedConfidentiality, // MC:L + V3MCNone: V3ModifiedConfidentiality, // MC:N + + V3MINotDefined: V3ModifiedIntegrity, // MI:X + V3MIHigh: V3ModifiedIntegrity, // MI:H + V3MILow: V3ModifiedIntegrity, // MI:L + V3MINone: V3ModifiedIntegrity, // MI:N + + V3MANotDefined: V3ModifiedAvailability, // MA:X + V3MAHigh: V3ModifiedAvailability, // MA:H + V3MALow: V3ModifiedAvailability, // MA:L + V3MANone: V3ModifiedAvailability, // MA:N +} + +// map of metric strings to metrics +var v3MetricStrLut = map[string]V3Metric { + "AV:N": V3AVNetwork, + "AV:A": V3AVAdjacentNetwork, + "AV:L": V3AVLocal, + "AV:P": V3AVPhysical, + + "AC:L": V3ACLow, + "AC:H": V3ACHigh, + + "PR:N": V3PRNone, + "PR:L": V3PRLow, + "PR:H": V3PRHigh, + + "UI:N": V3UINone, + "UI:R": V3UIRequired, + + "S:U": V3SUnchanged, + "S:C": V3SChanged, + + "C:H": V3CHigh, + "C:L": V3CLow, + "C:N": V3CNone, + + "I:H": V3IHigh, + "I:L": V3ILow, + "I:N": V3INone, + + "A:H": V3AHigh, + "A:L": V3ALow, + "A:N": V3ANone, + + "E:X": V3ENotDefined, + "E:H": V3EHigh, + "E:F": V3EFunctional, + "E:P": V3EProofOfConcept, + "E:U": V3EUnproven, + + "RL:X": V3RLNotDefined, + "RL:U": V3RLUnavailable, + "RL:W": V3RLWorkaround, + "RL:T": V3RLTemporaryFix, + "RL:O": V3RLOfficialFix, + + "RC:X": V3RCNotDefined, + "RC:C": V3RCConfirmed, + "RC:R": V3RCReasonable, + "RC:U": V3RCUnknown, + + "CR:X": V3CRNotDefined, + "CR:H": V3CRHigh, + "CR:M": V3CRMedium, + "CR:L": V3CRLow, + + "IR:X": V3IRNotDefined, + "IR:H": V3IRHigh, + "IR:M": V3IRMedium, + "IR:L": V3IRLow, + + "AR:X": V3ARNotDefined, + "AR:H": V3ARHigh, + "AR:M": V3ARMedium, + "AR:L": V3ARLow, + + "MAV:X": V3MAVNotDefined, + "MAV:N": V3MAVNetwork, + "MAV:A": V3MAVAdjacentNetwork, + "MAV:L": V3MAVLocal, + "MAV:P": V3MAVPhysical, + + "MAC:X": V3MACNotDefined, + "MAC:L": V3MACLow, + "MAC:H": V3MACHigh, + + "MPR:X": V3MMRNotDefined, + "MPR:L": V3MPRLow, + "MPR:H": V3MPRHigh, + + "MUI:X": V3MUINotDefined, + "MUI:N": V3MUINone, + "MUI:R": V3MUIRequired, + + "MMS:X": V3MSNotDefined, + "MMS:U": V3MSUnchanged, + "MMS:C": V3MSChanged, + + "MC:X": V3MCNotDefined, + "MC:H": V3MCHigh, + "MC:L": V3MCLow, + "MC:N": V3MCNone, + + "MI:X": V3MINotDefined, + "MI:H": V3MIHigh, + "MI:L": V3MILow, + "MI:N": V3MINone, + + "MA:X": V3MANotDefined, + "MA:H": V3MAHigh, + "MA:L": V3MALow, + "MA:N": V3MANone, +} + +// Convert string to CVSS 3.1 metric. +func GetV3MetricFromString(s string) (V3Metric, error) { + // get metric + m, ok := v3MetricStrLut[s] + if !ok { + return V3AVNetwork, fmt.Errorf("invalid metric: %s", s) + } + + // return success + return m, nil +} + +// 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 +} + +// create CVSS 3.0 vector from string +func NewV30VectorFromString(s string) (Vector, error) { + strs := strings.Split(s, "/") + r := make([]V3Metric, len(strs)) + + // walk metric strings + for i, ms := range(strs) { + // convert string to vector + m, err := GetV3MetricFromString(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 +} + +// create CVSS 3.1 vector from string +func NewV31VectorFromString(s string) (Vector, error) { + strs := strings.Split(s, "/") + r := make([]V3Metric, len(strs)) + + // walk metric strings + for i, ms := range(strs) { + // convert string to vector + m, err := GetV3MetricFromString(ms) + if err != nil { + return nil, err + } + + // add to results + r[i] = m + } + + // build and return vector + return v31Vector(r), nil +} + +// CVSS vector +type Vector interface { + // Get CVSS version. + Version() Version + + // Get CVSS vector string. + String() string +} + +// 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 NewV31VectorFromString(s[len(v31Prefix):]) + } else if len(s) > len(v30Prefix) && s[:len(v30Prefix)] == v30Prefix { + // create CVSS v3.0 vector. + return NewV30VectorFromString(s[len(v30Prefix):]) + } else { + // create CVSS V2 vector + return NewV2VectorFromString(s) + } +} diff --git a/internal/cvss/metriccategory_string.go b/internal/cvss/metriccategory_string.go new file mode 100644 index 0000000..9ad249c --- /dev/null +++ b/internal/cvss/metriccategory_string.go @@ -0,0 +1,25 @@ +// Code generated by "stringer -linecomment -type=MetricCategory"; DO NOT EDIT. + +package cvss + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Base-0] + _ = x[Temporal-1] + _ = x[Environmental-2] +} + +const _MetricCategory_name = "BaseTemporalEnvironmental" + +var _MetricCategory_index = [...]uint8{0, 4, 12, 25} + +func (i MetricCategory) String() string { + if i >= MetricCategory(len(_MetricCategory_index)-1) { + return "MetricCategory(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _MetricCategory_name[_MetricCategory_index[i]:_MetricCategory_index[i+1]] +} diff --git a/internal/cvss/v2metric_string.go b/internal/cvss/v2metric_string.go new file mode 100644 index 0000000..8191622 --- /dev/null +++ b/internal/cvss/v2metric_string.go @@ -0,0 +1,77 @@ +// Code generated by "stringer -linecomment -type=V2Metric"; DO NOT EDIT. + +package cvss + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[V2AVNetwork-0] + _ = x[V2AVAdjacentNetwork-1] + _ = x[V2AVLocal-2] + _ = x[V2ACLow-3] + _ = x[V2ACMedium-4] + _ = x[V2ACHigh-5] + _ = x[V2AuMultiple-6] + _ = x[V2AuSingle-7] + _ = x[V2AuNone-8] + _ = x[V2CNone-9] + _ = x[V2CPartial-10] + _ = x[V2CComplete-11] + _ = x[V2INone-12] + _ = x[V2IPartial-13] + _ = x[V2IComplete-14] + _ = x[V2ANone-15] + _ = x[V2APartial-16] + _ = x[V2AComplete-17] + _ = x[V2ENotDefined-18] + _ = x[V2EUnproven-19] + _ = x[V2EProofOfConcept-20] + _ = x[V2EFunctional-21] + _ = x[V2EHigh-22] + _ = x[V2RLOfficialFix-23] + _ = x[V2RLTemporaryFix-24] + _ = x[V2RLWorkaround-25] + _ = x[V2RLUnavailable-26] + _ = x[V2RLNotDefined-27] + _ = x[V2RCUnconfirmed-28] + _ = x[V2RCUncorroborated-29] + _ = x[V2RCConfirmed-30] + _ = x[V2RCNotDefined-31] + _ = x[V2CDPNone-32] + _ = x[V2CDPLow-33] + _ = x[V2CDPLowMedium-34] + _ = x[V2CDPMediumHigh-35] + _ = x[V2CDPHigh-36] + _ = x[V2CDPNotDefined-37] + _ = x[V2TDNone-38] + _ = x[V2TDLow-39] + _ = x[V2TDMedium-40] + _ = x[V2TDHigh-41] + _ = x[V2TDNotDefined-42] + _ = x[V2CRLow-43] + _ = x[V2CRMedium-44] + _ = x[V2CRHigh-45] + _ = x[V2CRNotDefined-46] + _ = x[V2IRLow-47] + _ = x[V2IRMedium-48] + _ = x[V2IRHigh-49] + _ = x[V2IRNotDefined-50] + _ = x[V2ARLow-51] + _ = x[V2ARMedium-52] + _ = x[V2ARHigh-53] + _ = x[V2ARNotDefined-54] +} + +const _V2Metric_name = "AV:NAV:AAV:LAC:LAC:LAC:HAu:MAu:SAu:NC:NC:PC:CI:NI:PI:CA:NA:PA:CE:NDE:UE:POCE:FE:HRL:OFRL:TFRL:WRL:URL:NDRC:UCRC:URRC:CRC:NDCDP:NCDP:LCDP:LMCDP:MHCDP:HCDP:NDTD:NTD:LTD:MTD:HTD:NDCR:LCR:MCR:HCR:NDIR:LIR:MIR:HIR:NDAR:LAR:MAR:HAR:ND" + +var _V2Metric_index = [...]uint8{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 67, 70, 75, 78, 81, 86, 91, 95, 99, 104, 109, 114, 118, 123, 128, 133, 139, 145, 150, 156, 160, 164, 168, 172, 177, 181, 185, 189, 194, 198, 202, 206, 211, 215, 219, 223, 228} + +func (i V2Metric) String() string { + if i >= V2Metric(len(_V2Metric_index)-1) { + return "V2Metric(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _V2Metric_name[_V2Metric_index[i]:_V2Metric_index[i+1]] +} diff --git a/internal/cvss/v2metrickey_string.go b/internal/cvss/v2metrickey_string.go new file mode 100644 index 0000000..52b9834 --- /dev/null +++ b/internal/cvss/v2metrickey_string.go @@ -0,0 +1,36 @@ +// Code generated by "stringer -linecomment -type=V2MetricKey"; DO NOT EDIT. + +package cvss + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[V2AccessVector-0] + _ = x[V2AccessComplexity-1] + _ = x[V2Authentication-2] + _ = x[V2ConfidentialityImpact-3] + _ = x[V2IntegrityImpact-4] + _ = x[V2AvailabilityImpact-5] + _ = x[V2Exploitability-6] + _ = x[V2RemediationLevel-7] + _ = x[V2ReportConfidence-8] + _ = x[V2CollateralDamagePotential-9] + _ = x[V2TargetDistribution-10] + _ = x[V2ConfidentialityRequirement-11] + _ = x[V2IntegrityRequirement-12] + _ = x[V2AvailabilityRequirement-13] +} + +const _V2MetricKey_name = "AVACAuCIAERLRCCDPTDCRIRAR" + +var _V2MetricKey_index = [...]uint8{0, 2, 4, 6, 7, 8, 9, 10, 12, 14, 17, 19, 21, 23, 25} + +func (i V2MetricKey) String() string { + if i >= V2MetricKey(len(_V2MetricKey_index)-1) { + return "V2MetricKey(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _V2MetricKey_name[_V2MetricKey_index[i]:_V2MetricKey_index[i+1]] +} diff --git a/internal/cvss/v3metric_string.go b/internal/cvss/v3metric_string.go new file mode 100644 index 0000000..e59b024 --- /dev/null +++ b/internal/cvss/v3metric_string.go @@ -0,0 +1,100 @@ +// Code generated by "stringer -linecomment -type=V3Metric"; DO NOT EDIT. + +package cvss + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[V3AVNetwork-0] + _ = x[V3AVAdjacentNetwork-1] + _ = x[V3AVLocal-2] + _ = x[V3AVPhysical-3] + _ = x[V3ACLow-4] + _ = x[V3ACHigh-5] + _ = x[V3PRNone-6] + _ = x[V3PRLow-7] + _ = x[V3PRHigh-8] + _ = x[V3UINone-9] + _ = x[V3UIRequired-10] + _ = x[V3SUnchanged-11] + _ = x[V3SChanged-12] + _ = x[V3CHigh-13] + _ = x[V3CLow-14] + _ = x[V3CNone-15] + _ = x[V3IHigh-16] + _ = x[V3ILow-17] + _ = x[V3INone-18] + _ = x[V3AHigh-19] + _ = x[V3ALow-20] + _ = x[V3ANone-21] + _ = x[V3ENotDefined-22] + _ = x[V3EHigh-23] + _ = x[V3EFunctional-24] + _ = x[V3EProofOfConcept-25] + _ = x[V3EUnproven-26] + _ = x[V3RLNotDefined-27] + _ = x[V3RLUnavailable-28] + _ = x[V3RLWorkaround-29] + _ = x[V3RLTemporaryFix-30] + _ = x[V3RLOfficialFix-31] + _ = x[V3RCNotDefined-32] + _ = x[V3RCConfirmed-33] + _ = x[V3RCReasonable-34] + _ = x[V3RCUnknown-35] + _ = x[V3CRNotDefined-36] + _ = x[V3CRHigh-37] + _ = x[V3CRMedium-38] + _ = x[V3CRLow-39] + _ = x[V3IRNotDefined-40] + _ = x[V3IRHigh-41] + _ = x[V3IRMedium-42] + _ = x[V3IRLow-43] + _ = x[V3ARNotDefined-44] + _ = x[V3ARHigh-45] + _ = x[V3ARMedium-46] + _ = x[V3ARLow-47] + _ = x[V3MAVNotDefined-48] + _ = x[V3MAVNetwork-49] + _ = x[V3MAVAdjacentNetwork-50] + _ = x[V3MAVLocal-51] + _ = x[V3MAVPhysical-52] + _ = x[V3MACNotDefined-53] + _ = x[V3MACLow-54] + _ = x[V3MACHigh-55] + _ = x[V3MMRNotDefined-56] + _ = x[V3MPRLow-57] + _ = x[V3MPRHigh-58] + _ = x[V3MUINotDefined-59] + _ = x[V3MUINone-60] + _ = x[V3MUIRequired-61] + _ = x[V3MSNotDefined-62] + _ = x[V3MSUnchanged-63] + _ = x[V3MSChanged-64] + _ = x[V3MCNotDefined-65] + _ = x[V3MCHigh-66] + _ = x[V3MCLow-67] + _ = x[V3MCNone-68] + _ = x[V3MINotDefined-69] + _ = x[V3MIHigh-70] + _ = x[V3MILow-71] + _ = x[V3MINone-72] + _ = x[V3MANotDefined-73] + _ = x[V3MAHigh-74] + _ = x[V3MALow-75] + _ = x[V3MANone-76] + _ = x[V3UnknownMetric-77] +} + +const _V3Metric_name = "AV:NAV:AAV:LAV:PAC:LAC:HPR:NPR:LPR:HUI:NUI:RS:US:CC:HC:LC:NI:HI:LI:NA:HA:LA:NE:XE:HE:FE:PE:URL:XRL:URL:WRL:TRL:ORC:XRC:CRC:RRC:UCR:XCR:HCR:MCR:LIR:XIR:HIR:MIR:LAR:XAR:HAR:MAR:LMAV:XMAV:NMAV:AMAV:LMAV:PMAC:XMAC:LMAC:HMPR:XMPR:LMPR:HMUI:XMUI:NMUI:RMMS:XMMS:UMMS:CMC:XMC:HMC:LMC:NMI:XMI:HMI:LMI:NMA:XMA:HMA:LMA:Nunknown" + +var _V3Metric_index = [...]uint16{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 181, 186, 191, 196, 201, 206, 211, 216, 221, 226, 231, 236, 241, 246, 251, 256, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 316} + +func (i V3Metric) String() string { + if i >= V3Metric(len(_V3Metric_index)-1) { + return "V3Metric(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _V3Metric_name[_V3Metric_index[i]:_V3Metric_index[i+1]] +} diff --git a/internal/cvss/v3metrickey_string.go b/internal/cvss/v3metrickey_string.go new file mode 100644 index 0000000..9459daa --- /dev/null +++ b/internal/cvss/v3metrickey_string.go @@ -0,0 +1,44 @@ +// Code generated by "stringer -linecomment -type=V3MetricKey"; DO NOT EDIT. + +package cvss + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[V3AttackVector-0] + _ = x[V3AttackComplexity-1] + _ = x[V3PrivilegesRequired-2] + _ = x[V3UserInteraction-3] + _ = x[V3Scope-4] + _ = x[V3Confidentiality-5] + _ = x[V3Integrity-6] + _ = x[V3Availability-7] + _ = x[V3ExploitCodeMaturity-8] + _ = x[V3RemediationLevel-9] + _ = x[V3ReportConfidence-10] + _ = x[V3ConfidentialityRequirement-11] + _ = x[V3IntegrityRequirement-12] + _ = x[V3AvailabilityRequirement-13] + _ = x[V3ModifiedAttackVector-14] + _ = x[V3ModifiedAttackComplexity-15] + _ = x[V3ModifiedPrivilegesRequired-16] + _ = x[V3ModifiedUserInteraction-17] + _ = x[V3ModifiedScope-18] + _ = x[V3ModifiedConfidentiality-19] + _ = x[V3ModifiedIntegrity-20] + _ = x[V3ModifiedAvailability-21] +} + +const _V3MetricKey_name = "AVACPRUISCIAERLRCCRIRARMAVMACMPRMUIMSMCMIMA" + +var _V3MetricKey_index = [...]uint8{0, 2, 4, 6, 8, 9, 10, 11, 12, 13, 15, 17, 19, 21, 23, 26, 29, 32, 35, 37, 39, 41, 43} + +func (i V3MetricKey) String() string { + if i >= V3MetricKey(len(_V3MetricKey_index)-1) { + return "V3MetricKey(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _V3MetricKey_name[_V3MetricKey_index[i]:_V3MetricKey_index[i+1]] +} diff --git a/internal/cvss/version_string.go b/internal/cvss/version_string.go new file mode 100644 index 0000000..03e8904 --- /dev/null +++ b/internal/cvss/version_string.go @@ -0,0 +1,25 @@ +// Code generated by "stringer -linecomment -type=Version"; DO NOT EDIT. + +package cvss + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[V20-0] + _ = x[V30-1] + _ = x[V31-2] +} + +const _Version_name = "2.03.03.1" + +var _Version_index = [...]uint8{0, 3, 6, 9} + +func (i Version) String() string { + if i >= Version(len(_Version_index)-1) { + return "Version(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Version_name[_Version_index[i]:_Version_index[i+1]] +} -- cgit v1.2.3