aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/cvss/v2key_test.go18
-rw-r--r--internal/cvss/v2metric_test.go9
-rw-r--r--internal/cvss/v3key_test.go18
-rw-r--r--internal/cvss/v3metric.go9
-rw-r--r--internal/cvss/v3metric_test.go366
-rw-r--r--internal/cvss/version_test.go24
6 files changed, 438 insertions, 6 deletions
diff --git a/internal/cvss/v2key_test.go b/internal/cvss/v2key_test.go
index 76a3d79..a54f4e7 100644
--- a/internal/cvss/v2key_test.go
+++ b/internal/cvss/v2key_test.go
@@ -96,3 +96,21 @@ func TestV2KeyCategory(t *testing.T) {
})
}
}
+
+func TestInvalidV2KeyName(t *testing.T) {
+ exp := "invalid"
+ got := v2Key(255).Name()
+
+ if got != exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, exp)
+ }
+}
+
+func TestInvalidV2KeyCategory(t *testing.T) {
+ exp := InvalidCategory
+ got := v2Key(255).Category()
+
+ if got != exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, exp)
+ }
+}
diff --git a/internal/cvss/v2metric_test.go b/internal/cvss/v2metric_test.go
index b17d2ed..f606ed5 100644
--- a/internal/cvss/v2metric_test.go
+++ b/internal/cvss/v2metric_test.go
@@ -265,3 +265,12 @@ func TestV2MetricString(t *testing.T) {
})
}
}
+
+func TestInvalidV2MetricKey(t *testing.T) {
+ got := v2Metric(255).Key()
+ exp := v2InvalidKey
+
+ if got != exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, exp)
+ }
+}
diff --git a/internal/cvss/v3key_test.go b/internal/cvss/v3key_test.go
index ccf2b8f..517eebd 100644
--- a/internal/cvss/v3key_test.go
+++ b/internal/cvss/v3key_test.go
@@ -122,3 +122,21 @@ func TestV3KeyCategory(t *testing.T) {
})
}
}
+
+func TestInvalidV3KeyName(t *testing.T) {
+ exp := "invalid"
+ got := v3Key(255).Name()
+
+ if got != exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, exp)
+ }
+}
+
+func TestInvalidV3KeyCategory(t *testing.T) {
+ exp := InvalidCategory
+ got := v3Key(255).Category()
+
+ if got != exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, exp)
+ }
+}
diff --git a/internal/cvss/v3metric.go b/internal/cvss/v3metric.go
index e9a6763..fc4c860 100644
--- a/internal/cvss/v3metric.go
+++ b/internal/cvss/v3metric.go
@@ -323,12 +323,9 @@ func (m v3Metric) Key() Key {
// Convert string to CVSS 3.1 metric.
func getV3Metric(version Version, s string) (v3Metric, error) {
- // get metric
- m, ok := v3MetricStrLut[s]
- if !ok {
+ if m, ok := v3MetricStrLut[s]; ok {
+ return m, nil
+ } else {
return v3InvalidMetric, newBadMetric(version, s)
}
-
- // return success
- return m, nil
}
diff --git a/internal/cvss/v3metric_test.go b/internal/cvss/v3metric_test.go
new file mode 100644
index 0000000..432d34a
--- /dev/null
+++ b/internal/cvss/v3metric_test.go
@@ -0,0 +1,366 @@
+package cvss
+
+import "testing"
+
+func TestGetV3Metric(t *testing.T) {
+ tests := []struct {
+ val string
+ exp v3Metric
+ ok bool
+ } {
+ { "AV:N", v3AVNetwork, true },
+ { "AV:A", v3AVAdjacentNetwork, true },
+ { "AV:L", v3AVLocal, true },
+ { "AV:P", v3AVPhysical, true },
+
+ { "AC:L", v3ACLow, true },
+ { "AC:H", v3ACHigh, true },
+
+ { "PR:N", v3PRNone, true },
+ { "PR:L", v3PRLow, true },
+ { "PR:H", v3PRHigh, true },
+
+ { "UI:N", v3UINone, true },
+ { "UI:R", v3UIRequired, true },
+
+ { "S:U", v3SUnchanged, true },
+ { "S:C", v3SChanged, true },
+
+ { "C:H", v3CHigh, true },
+ { "C:L", v3CLow, true },
+ { "C:N", v3CNone, true },
+
+ { "I:H", v3IHigh, true },
+ { "I:L", v3ILow, true },
+ { "I:N", v3INone, true },
+
+ { "A:H", v3AHigh, true },
+ { "A:L", v3ALow, true },
+ { "A:N", v3ANone, true },
+
+ { "E:X", v3ENotDefined, true },
+ { "E:H", v3EHigh, true },
+ { "E:F", v3EFunctional, true },
+ { "E:P", v3EProofOfConcept, true },
+ { "E:U", v3EUnproven, true },
+
+ { "RL:X", v3RLNotDefined, true },
+ { "RL:U", v3RLUnavailable, true },
+ { "RL:W", v3RLWorkaround, true },
+ { "RL:T", v3RLTemporaryFix, true },
+ { "RL:O", v3RLOfficialFix, true },
+
+ { "RC:X", v3RCNotDefined, true },
+ { "RC:C", v3RCConfirmed, true },
+ { "RC:R", v3RCReasonable, true },
+ { "RC:U", v3RCUnknown, true },
+
+ { "CR:X", v3CRNotDefined, true },
+ { "CR:H", v3CRHigh, true },
+ { "CR:M", v3CRMedium, true },
+ { "CR:L", v3CRLow, true },
+
+ { "IR:X", v3IRNotDefined, true },
+ { "IR:H", v3IRHigh, true },
+ { "IR:M", v3IRMedium, true },
+ { "IR:L", v3IRLow, true },
+
+ { "AR:X", v3ARNotDefined, true },
+ { "AR:H", v3ARHigh, true },
+ { "AR:M", v3ARMedium, true },
+ { "AR:L", v3ARLow, true },
+
+ { "MAV:X", v3MAVNotDefined, true },
+ { "MAV:N", v3MAVNetwork, true },
+ { "MAV:A", v3MAVAdjacentNetwork, true },
+ { "MAV:L", v3MAVLocal, true },
+ { "MAV:P", v3MAVPhysical, true },
+
+ { "MAC:X", v3MACNotDefined, true },
+ { "MAC:L", v3MACLow, true },
+ { "MAC:H", v3MACHigh, true },
+
+ { "MPR:X", v3MMRNotDefined, true },
+ { "MPR:L", v3MPRLow, true },
+ { "MPR:H", v3MPRHigh, true },
+
+ { "MUI:X", v3MUINotDefined, true },
+ { "MUI:N", v3MUINone, true },
+ { "MUI:R", v3MUIRequired, true },
+
+ { "MMS:X", v3MSNotDefined, true },
+ { "MMS:U", v3MSUnchanged, true },
+ { "MMS:C", v3MSChanged, true },
+
+ { "MC:X", v3MCNotDefined, true },
+ { "MC:H", v3MCHigh, true },
+ { "MC:L", v3MCLow, true },
+ { "MC:N", v3MCNone, true },
+
+ { "MI:X", v3MINotDefined, true },
+ { "MI:H", v3MIHigh, true },
+ { "MI:L", v3MILow, true },
+ { "MI:N", v3MINone, true },
+
+ { "MA:X", v3MANotDefined, true },
+ { "MA:H", v3MAHigh, true },
+ { "MA:L", v3MALow, true },
+ { "MA:N", v3MANone, true },
+
+ { "invalid", v3InvalidMetric, false },
+ }
+
+ for _, test := range(tests) {
+ t.Run(test.val, func(t *testing.T) {
+ got, err := getV3Metric(V31, test.val)
+ if test.ok && err == nil && got != test.exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, test.exp)
+ } else if test.ok && err != nil {
+ t.Error(err)
+ } else if !test.ok && err == nil {
+ t.Errorf("got: \"%s\", exp: error", got)
+ }
+ })
+ }
+}
+
+func TestGetV3MetricKey(t *testing.T) {
+ tests := []struct {
+ val v3Metric
+ exp v3Key
+ } {
+ { 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
+ }
+
+ for _, test := range(tests) {
+ t.Run(test.val.String(), func(t *testing.T) {
+ got := test.val.Key()
+ if got != test.exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, test.exp)
+ }
+ })
+ }
+}
+
+func TestV3MetricString(t *testing.T) {
+ tests := []struct {
+ val v3Metric
+ exp string
+ } {
+ { v3AVNetwork, "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" },
+
+ { v3Metric(255), "v3Metric(255)" },
+ }
+
+ for _, test := range(tests) {
+ t.Run(test.val.String(), func(t *testing.T) {
+ got := test.val.String()
+ if got != test.exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, test.exp)
+ }
+ })
+ }
+}
+
+func TestInvalidV3MetricKey(t *testing.T) {
+ got := v3Metric(255).Key()
+ exp := v3InvalidKey
+
+ if got != exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, exp)
+ }
+}
diff --git a/internal/cvss/version_test.go b/internal/cvss/version_test.go
new file mode 100644
index 0000000..e010094
--- /dev/null
+++ b/internal/cvss/version_test.go
@@ -0,0 +1,24 @@
+package cvss
+
+import "testing"
+
+func TestVersionString(t *testing.T) {
+ tests := []struct {
+ val Version
+ exp string
+ } {
+ { V20, "2.0" },
+ { V30, "3.0" },
+ { V31, "3.1" },
+ { Version(255), "Version(255)" },
+ }
+
+ for _, test := range(tests) {
+ t.Run(test.val.String(), func(t *testing.T) {
+ got := test.val.String()
+ if got != test.exp {
+ t.Errorf("got: \"%s\", exp: \"%s\"", got, test.exp)
+ }
+ })
+ }
+}