#![deny(missing_docs)]
#![deny(unsafe_code)]
mod encode;
pub mod v2;
pub mod v3;
pub mod v4;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Err {
Len,
Prefix,
DuplicateName,
UnknownName,
UnknownMetric,
MissingMandatoryMetrics,
UnknownSeverity,
InvalidMacroVector,
UnknownVersion,
UnknownNomenclature,
}
impl std::error::Error for Err {}
impl std::fmt::Display for Err {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", match self {
Err::Len => "String is too short to contain a CVSS vector string",
Err::Prefix => "String does not begin with a `CVSS:` prefix",
Err::DuplicateName => "Vector string contains a duplicate metric name",
Err::UnknownName => "Unknown metric name",
Err::UnknownMetric => "Vector string contains an unknown metric",
Err::MissingMandatoryMetrics => "Vector string is missing mandatory metrics",
Err::UnknownSeverity => "Unknown severity name",
Err::InvalidMacroVector => "Invalid macro vector digit",
Err::UnknownVersion => "Unknown CVSS version",
Err::UnknownNomenclature => "Unknown nomenclature",
})
}
}
const VAL_MASK: u64 = 0x0fff_ffff_ffff_ffff;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum MajorVersion {
V2,
V3,
V4,
}
impl From<Vector> for MajorVersion {
fn from(vec: Vector) -> MajorVersion {
match Version::from(vec) {
Version::V20 => MajorVersion::V2,
Version::V30 | Version::V31 => MajorVersion::V3,
Version::V40 => MajorVersion::V4,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u8)]
pub enum Version {
V20 = 0,
V30 = 1,
V31 = 2,
V40 = 3,
}
impl std::fmt::Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", match self {
Version::V20 => "2.0",
Version::V30 => "3.0",
Version::V31 => "3.1",
Version::V40 => "4.0",
})
}
}
impl std::str::FromStr for Version {
type Err = Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"2.0" => Ok(Version::V20),
"3.0" => Ok(Version::V30),
"3.1" => Ok(Version::V31),
"4.0" => Ok(Version::V40),
_ => Err(Err::UnknownVersion),
}
}
}
impl From<Version> for u64 {
fn from(v: Version) -> u64 {
(v as u64) << 60
}
}
impl From<Vector> for Version {
fn from(vec: Vector) -> Version {
match Version::try_from(vec.0) {
Ok(version) => version,
Err(err) => panic!("{err}"),
}
}
}
impl TryFrom<u64> for Version {
type Error = Err;
fn try_from(val: u64) -> Result<Version, Self::Error> {
match val >> 60 {
0 => Ok(Version::V20),
1 => Ok(Version::V30),
2 => Ok(Version::V31),
3 => Ok(Version::V40),
_ => Err(Err::UnknownVersion),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Group {
V2(v2::Group),
V3(v3::Group),
V4(v4::Group),
}
impl From<Name> for Group {
fn from(name: Name) -> Group {
match name {
Name::V2(n) => Group::V2(v2::Group::from(n)),
Name::V3(n) => Group::V3(v3::Group::from(n)),
Name::V4(n) => Group::V4(v4::Group::from(n)),
}
}
}
impl From<Metric> for Group {
fn from(m: Metric) -> Group {
Group::from(Name::from(m))
}
}
impl From<v2::Group> for Group {
fn from(group: v2::Group) -> Group {
Group::V2(group)
}
}
impl From<v3::Group> for Group {
fn from(group: v3::Group) -> Group {
Group::V3(group)
}
}
impl From<v4::Group> for Group {
fn from(group: v4::Group) -> Group {
Group::V4(group)
}
}
impl std::fmt::Display for Group {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
Group::V2(group) => group.fmt(f),
Group::V3(group) => group.fmt(f),
Group::V4(group) => group.fmt(f),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Name {
V2(v2::Name),
V3(v3::Name),
V4(v4::Name),
}
impl From<Metric> for Name {
fn from(m: Metric) -> Name {
match m {
Metric::V2(m) => Name::V2(v2::Name::from(m)),
Metric::V3(m) => Name::V3(v3::Name::from(m)),
Metric::V4(m) => Name::V4(v4::Name::from(m)),
}
}
}
impl From<v2::Metric> for Name {
fn from(m: v2::Metric) -> Name {
Name::V2(v2::Name::from(m))
}
}
impl From<v3::Metric> for Name {
fn from(m: v3::Metric) -> Name {
Name::V3(v3::Name::from(m))
}
}
impl From<v4::Metric> for Name {
fn from(m: v4::Metric) -> Name {
Name::V4(v4::Name::from(m))
}
}
impl From<v2::Name> for Name {
fn from(m: v2::Name) -> Name {
Name::V2(m)
}
}
impl From<v3::Name> for Name {
fn from(m: v3::Name) -> Name {
Name::V3(m)
}
}
impl From<v4::Name> for Name {
fn from(m: v4::Name) -> Name {
Name::V4(m)
}
}
impl std::fmt::Display for Name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
Name::V2(name) => name.fmt(f),
Name::V3(name) => name.fmt(f),
Name::V4(name) => name.fmt(f),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Metric {
V2(v2::Metric),
V3(v3::Metric),
V4(v4::Metric),
}
impl From<v2::Metric> for Metric {
fn from(m: v2::Metric) -> Metric {
Metric::V2(m)
}
}
impl From<v3::Metric> for Metric {
fn from(m: v3::Metric) -> Metric {
Metric::V3(m)
}
}
impl From<v4::Metric> for Metric {
fn from(m: v4::Metric) -> Metric {
Metric::V4(m)
}
}
impl std::fmt::Display for Metric {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
Metric::V2(m) => m.fmt(f),
Metric::V3(m) => m.fmt(f),
Metric::V4(m) => m.fmt(f),
}
}
}
pub enum VectorIterator {
V2(v2::VectorIterator),
V3(v3::VectorIterator),
V4(v4::VectorIterator),
}
impl Iterator for VectorIterator {
type Item = Metric;
fn next(&mut self) -> Option<Metric> {
match self {
VectorIterator::V2(iter) => iter.next().map(Metric::V2),
VectorIterator::V3(iter) => iter.next().map(Metric::V3),
VectorIterator::V4(iter) => iter.next().map(Metric::V4),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Vector(u64);
impl Vector {
pub fn get(self, name: Name) -> Result<Metric, Err> {
match (MajorVersion::from(self), name) {
(MajorVersion::V2, Name::V2(name)) => Ok(Metric::V2(v2::Vector::from(self).get(name))),
(MajorVersion::V3, Name::V3(name)) => Ok(Metric::V3(v3::Vector::from(self).get(name))),
(MajorVersion::V4, Name::V4(name)) => Ok(Metric::V4(v4::Vector::from(self).get(name))),
_ => Err(Err::UnknownName),
}
}
pub fn base_score(&self) -> Score {
match MajorVersion::from(*self) {
MajorVersion::V2 => v2::Scores::from(v2::Vector::from(*self)).base,
MajorVersion::V3 => v3::Scores::from(v3::Vector::from(*self)).base,
MajorVersion::V4 => Score::from(v4::Vector::from(*self)),
}
}
}
impl IntoIterator for Vector {
type Item = Metric;
type IntoIter = VectorIterator;
fn into_iter(self) -> Self::IntoIter {
match MajorVersion::from(self) {
MajorVersion::V2 => Self::IntoIter::V2(v2::Vector::from(self).into_iter()),
MajorVersion::V3 => Self::IntoIter::V3(v3::Vector::from(self).into_iter()),
MajorVersion::V4 => Self::IntoIter::V4(v4::Vector::from(self).into_iter()),
}
}
}
impl std::str::FromStr for Vector {
type Err = Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() < 9 {
return Err(Err::Len);
}
Ok(Vector(match &s[0..9] {
"CVSS:4.0/" => u64::from(v4::Vector::from_str(s)?),
"CVSS:3.0/" | "CVSS:3.1/" => u64::from(v3::Vector::from_str(s)?),
_ => u64::from(v2::Vector::from_str(s)?),
}))
}
}
impl TryFrom<String> for Vector {
type Error = Err;
fn try_from(s: String) -> Result<Self, Self::Error> {
s.parse::<Vector>()
}
}
impl From<Vector> for Score {
fn from(vec: Vector) -> Score {
match MajorVersion::from(vec) {
MajorVersion::V2 => Score::from(v2::Vector::from(vec)),
MajorVersion::V3 => Score::from(v3::Vector::from(vec)),
MajorVersion::V4 => Score::from(v4::Vector::from(vec)),
}
}
}
impl std::fmt::Display for Vector {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match MajorVersion::from(*self) {
MajorVersion::V2 => v2::Vector::from(*self).fmt(f),
MajorVersion::V3 => v3::Vector::from(*self).fmt(f),
MajorVersion::V4 => v4::Vector::from(*self).fmt(f),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Score(u8);
impl From<f32> for Score {
fn from(val: f32) -> Score {
Score((val * 10.0).round().clamp(0.0, 100.0) as u8)
}
}
impl From<f64> for Score {
fn from(val: f64) -> Score {
Score((val * 10.0).round().clamp(0.0, 100.0) as u8)
}
}
impl From<Score> for f32 {
fn from(score: Score) -> f32 {
(score.0 as f32) / 10.0
}
}
impl From<Score> for f64 {
fn from(score: Score) -> f64 {
(score.0 as f64) / 10.0
}
}
impl std::fmt::Display for Score {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{:1.1}", f32::from(*self))
}
}
impl std::ops::Add for Score {
type Output = Self;
fn add(self, other: Self) -> Self {
Self(self.0 + other.0).clamp(Self(0), Self(100))
}
}
impl std::ops::Sub for Score {
type Output = Self;
fn sub(self, other: Self) -> Self {
Self(self.0 - other.0).clamp(Self(0), Self(100))
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u8)]
pub enum Severity {
None,
Low,
Medium,
High,
Critical,
}
impl From<Score> for Severity {
fn from(score: Score) -> Severity {
match score.0 {
0 => Severity::None,
1..40 => Severity::Low,
40..70 => Severity::Medium,
70..90 => Severity::High,
_ => Severity::Critical,
}
}
}
impl From<Vector> for Severity {
fn from(vec: Vector) -> Severity {
Severity::from(Score::from(vec))
}
}
impl std::str::FromStr for Severity {
type Err = Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"NONE" => Ok(Severity::None),
"LOW" => Ok(Severity::Low),
"MEDIUM" => Ok(Severity::Medium),
"HIGH" => Ok(Severity::High),
"CRITICAL" => Ok(Severity::Critical),
_ => Err(Err::UnknownSeverity),
}
}
}
impl std::fmt::Display for Severity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", match self {
Severity::None => "NONE",
Severity::Low => "LOW",
Severity::Medium => "MEDIUM",
Severity::High => "HIGH",
Severity::Critical => "CRITICAL",
})
}
}
#[cfg(test)]
mod tests {
mod err {
use super::super::Err;
#[test]
fn test_to_string() {
let tests = vec![
(Err::Len, "String is too short to contain a CVSS vector string"),
(Err::Prefix, "String does not begin with a `CVSS:` prefix"),
(Err::DuplicateName, "Vector string contains a duplicate metric name"),
(Err::UnknownName, "Unknown metric name"),
(Err::UnknownMetric, "Vector string contains an unknown metric"),
(Err::MissingMandatoryMetrics, "Vector string is missing mandatory metrics"),
(Err::UnknownSeverity, "Unknown severity name"),
(Err::InvalidMacroVector, "Invalid macro vector digit"),
(Err::UnknownVersion, "Unknown CVSS version"),
(Err::UnknownNomenclature, "Unknown nomenclature"),
];
for (err, exp) in tests {
assert_eq!(err.to_string(), exp, "{err:?}");
}
}
}
mod version {
use super::super::{Err, Version};
#[test]
fn test_from_str_fail() {
let tests = vec!["", "asdf", "1.0"];
for t in tests {
assert_eq!(t.parse::<Version>(), Err(Err::UnknownVersion), "{t}");
}
}
#[test]
fn test_from_str_pass() {
let tests = vec![
("2.0", Version::V20),
("3.0", Version::V30),
("3.1", Version::V31),
("4.0", Version::V40),
];
for (s, exp) in tests {
assert_eq!(s.parse::<Version>(), Ok(exp), "{s}");
}
}
#[test]
fn test_to_string() {
let tests = vec![
(Version::V20, "2.0"),
(Version::V30, "3.0"),
(Version::V31, "3.1"),
(Version::V40, "4.0"),
];
for (v, exp) in tests {
assert_eq!(v.to_string(), exp, "{exp}");
}
}
#[test]
fn test_try_from_u64_fail() {
for t in 7..16 {
assert_eq!(Version::try_from(t << 60), Err(Err::UnknownVersion), "{t}");
}
}
#[test]
fn test_try_from_u64_pass() {
for t in 0..4 {
Version::try_from(t << 60).expect(&t.to_string());
}
}
}
mod group {
use super::super::{Group, v2, v3, v4};
#[test]
fn test_from_name() {
use super::super::Name;
let tests = vec![
(Name::V2(v2::Name::AccessVector), Group::V2(v2::Group::Base)),
(Name::V2(v2::Name::AccessComplexity), Group::V2(v2::Group::Base)),
(Name::V2(v2::Name::Authentication), Group::V2(v2::Group::Base)),
(Name::V2(v2::Name::Confidentiality), Group::V2(v2::Group::Base)),
(Name::V2(v2::Name::Integrity), Group::V2(v2::Group::Base)),
(Name::V2(v2::Name::Availability), Group::V2(v2::Group::Base)),
(Name::V2(v2::Name::Exploitability), Group::V2(v2::Group::Temporal)),
(Name::V2(v2::Name::RemediationLevel), Group::V2(v2::Group::Temporal)),
(Name::V2(v2::Name::ReportConfidence), Group::V2(v2::Group::Temporal)),
(Name::V2(v2::Name::CollateralDamagePotential), Group::V2(v2::Group::Environmental)),
(Name::V2(v2::Name::TargetDistribution), Group::V2(v2::Group::Environmental)),
(Name::V2(v2::Name::ConfidentialityRequirement), Group::V2(v2::Group::Environmental)),
(Name::V2(v2::Name::IntegrityRequirement), Group::V2(v2::Group::Environmental)),
(Name::V2(v2::Name::AvailabilityRequirement), Group::V2(v2::Group::Environmental)),
(Name::V3(v3::Name::AttackVector), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::AttackComplexity), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::PrivilegesRequired), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::UserInteraction), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::Scope), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::Confidentiality), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::Integrity), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::Availability), Group::V3(v3::Group::Base)),
(Name::V3(v3::Name::ExploitCodeMaturity), Group::V3(v3::Group::Temporal)),
(Name::V3(v3::Name::RemediationLevel), Group::V3(v3::Group::Temporal)),
(Name::V3(v3::Name::ReportConfidence), Group::V3(v3::Group::Temporal)),
(Name::V3(v3::Name::ConfidentialityRequirement), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::IntegrityRequirement), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::AvailabilityRequirement), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedAttackVector), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedAttackComplexity), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedPrivilegesRequired), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedUserInteraction), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedScope), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedConfidentiality), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedIntegrity), Group::V3(v3::Group::Environmental)),
(Name::V3(v3::Name::ModifiedAvailability), Group::V3(v3::Group::Environmental)),
(Name::V4(v4::Name::AttackVector), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::AttackComplexity), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::AttackRequirements), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::PrivilegesRequired), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::UserInteraction), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::VulnerableSystemConfidentialityImpact), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::VulnerableSystemIntegrityImpact), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::VulnerableSystemAvailabilityImpact), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::SubsequentSystemConfidentialityImpact), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::SubsequentSystemIntegrityImpact), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::SubsequentSystemAvailabilityImpact), Group::V4(v4::Group::Base)),
(Name::V4(v4::Name::ExploitMaturity), Group::V4(v4::Group::Threat)),
(Name::V4(v4::Name::ConfidentialityRequirement), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::IntegrityRequirement), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::AvailabilityRequirement), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedAttackVector), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedAttackComplexity), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedAttackRequirements), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedPrivilegesRequired), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedUserInteraction), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedVulnerableSystemConfidentiality), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedVulnerableSystemIntegrity), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedVulnerableSystemAvailability), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedSubsequentSystemConfidentiality), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedSubsequentSystemIntegrity), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::ModifiedSubsequentSystemAvailability), Group::V4(v4::Group::Environmental)),
(Name::V4(v4::Name::Safety), Group::V4(v4::Group::Supplemental)),
(Name::V4(v4::Name::Automatable), Group::V4(v4::Group::Supplemental)),
(Name::V4(v4::Name::Recovery), Group::V4(v4::Group::Supplemental)),
(Name::V4(v4::Name::ValueDensity), Group::V4(v4::Group::Supplemental)),
(Name::V4(v4::Name::VulnerabilityResponseEffort), Group::V4(v4::Group::Supplemental)),
(Name::V4(v4::Name::ProviderUrgency), Group::V4(v4::Group::Supplemental)),
];
for (name, exp) in tests {
assert_eq!(Group::from(name), exp);
}
}
#[test]
fn test_from_metric() {
use super::super::Metric;
let tests = vec![
(Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Local)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::AccessVector(v2::AccessVector::AdjacentNetwork)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::High)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Medium)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Low)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Authentication(v2::Authentication::Multiple)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Authentication(v2::Authentication::Single)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Authentication(v2::Authentication::None)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Confidentiality(v2::Impact::None)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Confidentiality(v2::Impact::Partial)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Confidentiality(v2::Impact::Complete)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Integrity(v2::Impact::None)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Integrity(v2::Impact::Partial)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Integrity(v2::Impact::Complete)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Availability(v2::Impact::None)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Availability(v2::Impact::Partial)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Availability(v2::Impact::Complete)), Group::V2(v2::Group::Base)),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::NotDefined)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::Unproven)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::ProofOfConcept)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::Functional)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::High)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::NotDefined)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::OfficialFix)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::TemporaryFix)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::Workaround)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::Unavailable)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::NotDefined)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Unconfirmed)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Uncorroborated)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Confirmed)), Group::V2(v2::Group::Temporal)),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::NotDefined)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::None)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::Low)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::LowMedium)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::MediumHigh)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::High)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::NotDefined)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::None)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::Low)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::Medium)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::High)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::NotDefined)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::Low)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::Medium)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::High)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::NotDefined)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::Low)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::Medium)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::High)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::NotDefined)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::Low)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::Medium)), Group::V2(v2::Group::Environmental)),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::High)), Group::V2(v2::Group::Environmental)),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Network)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Adjacent)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Local)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Physical)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::High)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::Low)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::High)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::Low)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::None)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::None)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::Required)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Scope(v3::Scope::Unchanged)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Scope(v3::Scope::Changed)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Confidentiality(v3::Impact::None)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Confidentiality(v3::Impact::Low)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Confidentiality(v3::Impact::High)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Integrity(v3::Impact::None)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Integrity(v3::Impact::Low)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Integrity(v3::Impact::High)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Availability(v3::Impact::None)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Availability(v3::Impact::Low)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::Availability(v3::Impact::High)), Group::V3(v3::Group::Base)),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::Unproven)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::ProofOfConcept)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::Functional)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::High)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::NotDefined)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::OfficialFix)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::TemporaryFix)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::Workaround)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::Unavailable)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::NotDefined)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Unknown)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Reasonable)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Confirmed)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::NotDefined)), Group::V3(v3::Group::Temporal)),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::Medium)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::Medium)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::Medium)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Network)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Adjacent)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Local)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Physical)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::None)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::None)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::Required)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::Unchanged)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::Changed)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::None)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::None)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::None)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::Low)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::High)), Group::V3(v3::Group::Environmental)),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::NotDefined)), Group::V3(v3::Group::Environmental)),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Network)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Adjacent)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Local)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Physical)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::Present)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::Passive)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::Active)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::High)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::Low)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::None)), Group::V4(v4::Group::Base)),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::NotDefined)), Group::V4(v4::Group::Threat)),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::Attacked)), Group::V4(v4::Group::Threat)),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::ProofOfConcept)), Group::V4(v4::Group::Threat)),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::Unreported)), Group::V4(v4::Group::Threat)),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::Medium)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::Medium)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::Medium)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Network)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Adjacent)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Local)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Physical)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::Present)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::Passive)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::Active)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::Safety)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::NotDefined)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::High)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::Low)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::None)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::Safety)), Group::V4(v4::Group::Environmental)),
(Metric::V4(v4::Metric::Safety(v4::Safety::NotDefined)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Safety(v4::Safety::Present)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Safety(v4::Safety::Negligible)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Automatable(v4::Automatable::NotDefined)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Automatable(v4::Automatable::No)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Automatable(v4::Automatable::Yes)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::NotDefined)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::Automatic)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::User)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::Irrecoverable)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::NotDefined)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::Diffuse)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::Concentrated)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::NotDefined)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::Low)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::Moderate)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::High)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::NotDefined)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Red)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Amber)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Green)), Group::V4(v4::Group::Supplemental)),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Clear)), Group::V4(v4::Group::Supplemental)),
];
for (metric, exp) in tests {
assert_eq!(Group::from(metric), exp);
}
}
#[test]
fn test_from_v2_group() {
let tests = vec![
(v2::Group::Base, Group::V2(v2::Group::Base)),
(v2::Group::Temporal, Group::V2(v2::Group::Temporal)),
(v2::Group::Environmental, Group::V2(v2::Group::Environmental)),
];
for (group, exp) in tests {
assert_eq!(Group::from(group), exp);
}
}
#[test]
fn test_from_v3_group() {
let tests = vec![
(v3::Group::Base, Group::V3(v3::Group::Base)),
(v3::Group::Temporal, Group::V3(v3::Group::Temporal)),
(v3::Group::Environmental, Group::V3(v3::Group::Environmental)),
];
for (group, exp) in tests {
assert_eq!(Group::from(group), exp);
}
}
#[test]
fn test_from_v4_group() {
let tests = vec![
(v4::Group::Base, Group::V4(v4::Group::Base)),
(v4::Group::Threat, Group::V4(v4::Group::Threat)),
(v4::Group::Environmental, Group::V4(v4::Group::Environmental)),
(v4::Group::Supplemental, Group::V4(v4::Group::Supplemental)),
];
for (group, exp) in tests {
assert_eq!(Group::from(group), exp);
}
}
#[test]
fn test_to_string() {
let tests = vec![
(Group::V2(v2::Group::Base), "Base"),
(Group::V2(v2::Group::Temporal), "Temporal"),
(Group::V2(v2::Group::Environmental), "Environmental"),
(Group::V3(v3::Group::Base), "Base"),
(Group::V3(v3::Group::Temporal), "Temporal"),
(Group::V3(v3::Group::Environmental), "Environmental"),
(Group::V4(v4::Group::Base), "Base"),
(Group::V4(v4::Group::Threat), "Threat"),
(Group::V4(v4::Group::Environmental), "Environmental"),
(Group::V4(v4::Group::Supplemental), "Supplemental"),
];
for (group, exp) in tests {
assert_eq!(group.to_string(), exp);
}
}
}
mod name {
use super::super::{Name, v2, v3, v4};
#[test]
fn test_from_v2_metric() {
let tests = vec![(
v2::Metric::AccessVector(v2::AccessVector::Network),
Name::V2(v2::Name::AccessVector),
)];
for (metric, exp) in tests {
assert_eq!(Name::from(metric), exp, "{metric:?}");
}
}
#[test]
fn test_from_v3_metric() {
let tests = vec![(
v3::Metric::AttackVector(v3::AttackVector::Network),
Name::V3(v3::Name::AttackVector),
)];
for (metric, exp) in tests {
assert_eq!(Name::from(metric), exp, "{metric:?}");
}
}
#[test]
fn test_from_v4_metric() {
let tests = vec![(
v4::Metric::AttackVector(v4::AttackVector::Network),
Name::V4(v4::Name::AttackVector),
)];
for (metric, exp) in tests {
assert_eq!(Name::from(metric), exp, "{metric:?}");
}
}
#[test]
fn test_from_v2_name() {
let tests = vec![
(v2::Name::AccessVector, Name::V2(v2::Name::AccessVector)),
];
for (name, exp) in tests {
assert_eq!(Name::from(name), exp, "{name:?}");
}
}
#[test]
fn test_from_v3_name() {
let tests = vec![
(v3::Name::AttackVector, Name::V3(v3::Name::AttackVector)),
];
for (name, exp) in tests {
assert_eq!(Name::from(name), exp, "{name:?}");
}
}
#[test]
fn test_from_v4_name() {
let tests = vec![
(v4::Name::AttackVector, Name::V4(v4::Name::AttackVector)),
];
for (name, exp) in tests {
assert_eq!(Name::from(name), exp, "{name:?}");
}
}
#[test]
fn test_to_string() {
let tests = vec![
(Name::V2(v2::Name::AccessVector), "AV"),
(Name::V2(v2::Name::AccessComplexity), "AC"),
(Name::V2(v2::Name::Authentication), "Au"),
(Name::V2(v2::Name::Confidentiality), "C"),
(Name::V2(v2::Name::Integrity), "I"),
(Name::V2(v2::Name::Availability), "A"),
(Name::V2(v2::Name::Exploitability), "E"),
(Name::V2(v2::Name::RemediationLevel), "RL"),
(Name::V2(v2::Name::ReportConfidence), "RC"),
(Name::V2(v2::Name::CollateralDamagePotential), "CDP"),
(Name::V2(v2::Name::TargetDistribution), "TD"),
(Name::V2(v2::Name::ConfidentialityRequirement), "CR"),
(Name::V2(v2::Name::IntegrityRequirement), "IR"),
(Name::V2(v2::Name::AvailabilityRequirement), "AR"),
(Name::V3(v3::Name::AttackVector), "AV"),
(Name::V3(v3::Name::AttackComplexity), "AC"),
(Name::V3(v3::Name::PrivilegesRequired), "PR"),
(Name::V3(v3::Name::UserInteraction), "UI"),
(Name::V3(v3::Name::Scope), "S"),
(Name::V3(v3::Name::Confidentiality), "C"),
(Name::V3(v3::Name::Integrity), "I"),
(Name::V3(v3::Name::Availability), "A"),
(Name::V3(v3::Name::ExploitCodeMaturity), "E"),
(Name::V3(v3::Name::RemediationLevel), "RL"),
(Name::V3(v3::Name::ReportConfidence), "RC"),
(Name::V3(v3::Name::ConfidentialityRequirement), "CR"),
(Name::V3(v3::Name::IntegrityRequirement), "IR"),
(Name::V3(v3::Name::AvailabilityRequirement), "AR"),
(Name::V3(v3::Name::ModifiedAttackVector), "MAV"),
(Name::V3(v3::Name::ModifiedAttackComplexity), "MAC"),
(Name::V3(v3::Name::ModifiedPrivilegesRequired), "MPR"),
(Name::V3(v3::Name::ModifiedUserInteraction), "MUI"),
(Name::V3(v3::Name::ModifiedScope), "MS"),
(Name::V3(v3::Name::ModifiedConfidentiality), "MC"),
(Name::V3(v3::Name::ModifiedIntegrity), "MI"),
(Name::V3(v3::Name::ModifiedAvailability), "MA"),
(Name::V4(v4::Name::AttackVector), "AV"),
(Name::V4(v4::Name::AttackComplexity), "AC"),
(Name::V4(v4::Name::AttackRequirements), "AT"),
(Name::V4(v4::Name::PrivilegesRequired), "PR"),
(Name::V4(v4::Name::UserInteraction), "UI"),
(Name::V4(v4::Name::VulnerableSystemConfidentialityImpact), "VC"),
(Name::V4(v4::Name::VulnerableSystemIntegrityImpact), "VI"),
(Name::V4(v4::Name::VulnerableSystemAvailabilityImpact), "VA"),
(Name::V4(v4::Name::SubsequentSystemConfidentialityImpact), "SC"),
(Name::V4(v4::Name::SubsequentSystemIntegrityImpact), "SI"),
(Name::V4(v4::Name::SubsequentSystemAvailabilityImpact), "SA"),
(Name::V4(v4::Name::ExploitMaturity), "E"),
(Name::V4(v4::Name::ConfidentialityRequirement), "CR"),
(Name::V4(v4::Name::IntegrityRequirement), "IR"),
(Name::V4(v4::Name::AvailabilityRequirement), "AR"),
(Name::V4(v4::Name::ModifiedAttackVector), "MAV"),
(Name::V4(v4::Name::ModifiedAttackComplexity), "MAC"),
(Name::V4(v4::Name::ModifiedAttackRequirements), "MAT"),
(Name::V4(v4::Name::ModifiedPrivilegesRequired), "MPR"),
(Name::V4(v4::Name::ModifiedUserInteraction), "MUI"),
(Name::V4(v4::Name::ModifiedVulnerableSystemConfidentiality), "MVC"),
(Name::V4(v4::Name::ModifiedVulnerableSystemIntegrity), "MVI"),
(Name::V4(v4::Name::ModifiedVulnerableSystemAvailability), "MVA"),
(Name::V4(v4::Name::ModifiedSubsequentSystemConfidentiality), "MSC"),
(Name::V4(v4::Name::ModifiedSubsequentSystemIntegrity), "MSI"),
(Name::V4(v4::Name::ModifiedSubsequentSystemAvailability), "MSA"),
(Name::V4(v4::Name::Safety), "S"),
(Name::V4(v4::Name::Automatable), "AU"),
(Name::V4(v4::Name::Recovery), "R"),
(Name::V4(v4::Name::ValueDensity), "V"),
(Name::V4(v4::Name::VulnerabilityResponseEffort), "RE"),
(Name::V4(v4::Name::ProviderUrgency), "U"),
];
for (name, exp) in tests {
assert_eq!(name.to_string(), exp, "{exp}");
}
}
}
mod metric {
use super::super::{Metric, v2, v3, v4};
#[test]
fn test_from_v2_metric() {
let tests = vec![(
v2::Metric::AccessVector(v2::AccessVector::Network),
Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network)),
)];
for (metric, exp) in tests {
assert_eq!(Metric::from(metric), exp, "{metric:?}");
}
}
#[test]
fn test_from_v3_metric() {
let tests = vec![(
v3::Metric::AttackVector(v3::AttackVector::Network),
Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Network)),
)];
for (metric, exp) in tests {
assert_eq!(Metric::from(metric), exp, "{metric:?}");
}
}
#[test]
fn test_from_v4_metric() {
let tests = vec![(
v4::Metric::AttackVector(v4::AttackVector::Network),
Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Network)),
)];
for (metric, exp) in tests {
assert_eq!(Metric::from(metric), exp, "{metric:?}");
}
}
#[test]
fn test_to_string() {
let tests = vec![
(Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Local)), "AV:L"),
(Metric::V2(v2::Metric::AccessVector(v2::AccessVector::AdjacentNetwork)), "AV:A"),
(Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network)), "AV:N"),
(Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::High)), "AC:H"),
(Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Medium)), "AC:M"),
(Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Low)), "AC:L"),
(Metric::V2(v2::Metric::Authentication(v2::Authentication::Multiple)), "Au:M"),
(Metric::V2(v2::Metric::Authentication(v2::Authentication::Single)), "Au:S"),
(Metric::V2(v2::Metric::Authentication(v2::Authentication::None)), "Au:N"),
(Metric::V2(v2::Metric::Confidentiality(v2::Impact::None)), "C:N"),
(Metric::V2(v2::Metric::Confidentiality(v2::Impact::Partial)), "C:P"),
(Metric::V2(v2::Metric::Confidentiality(v2::Impact::Complete)), "C:C"),
(Metric::V2(v2::Metric::Integrity(v2::Impact::None)), "I:N"),
(Metric::V2(v2::Metric::Integrity(v2::Impact::Partial)), "I:P"),
(Metric::V2(v2::Metric::Integrity(v2::Impact::Complete)), "I:C"),
(Metric::V2(v2::Metric::Availability(v2::Impact::None)), "A:N"),
(Metric::V2(v2::Metric::Availability(v2::Impact::Partial)), "A:P"),
(Metric::V2(v2::Metric::Availability(v2::Impact::Complete)), "A:C"),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::NotDefined)), "E:ND"),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::Unproven)), "E:U"),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::ProofOfConcept)), "E:POC"),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::Functional)), "E:F"),
(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::High)), "E:H"),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::NotDefined)), "RL:ND"),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::OfficialFix)), "RL:OF"),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::TemporaryFix)), "RL:TF"),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::Workaround)), "RL:W"),
(Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::Unavailable)), "RL:U"),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::NotDefined)), "RC:ND"),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Unconfirmed)), "RC:UC"),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Uncorroborated)), "RC:UR"),
(Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Confirmed)), "RC:C"),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::NotDefined)), "CDP:ND"),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::None)), "CDP:N"),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::Low)), "CDP:L"),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::LowMedium)), "CDP:LM"),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::MediumHigh)), "CDP:MH"),
(Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::High)), "CDP:H"),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::NotDefined)), "TD:ND"),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::None)), "TD:N"),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::Low)), "TD:L"),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::Medium)), "TD:M"),
(Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::High)), "TD:H"),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::NotDefined)), "CR:ND"),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::Low)), "CR:L"),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::Medium)), "CR:M"),
(Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::High)), "CR:H"),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::NotDefined)), "IR:ND"),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::Low)), "IR:L"),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::Medium)), "IR:M"),
(Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::High)), "IR:H"),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::NotDefined)), "AR:ND"),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::Low)), "AR:L"),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::Medium)), "AR:M"),
(Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::High)), "AR:H"),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Network)), "AV:N"),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Adjacent)), "AV:A"),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Local)), "AV:L"),
(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Physical)), "AV:P"),
(Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::High)), "AC:H"),
(Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::Low)), "AC:L"),
(Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::High)), "PR:H"),
(Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::Low)), "PR:L"),
(Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::None)), "PR:N"),
(Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::None)), "UI:N"),
(Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::Required)), "UI:R"),
(Metric::V3(v3::Metric::Scope(v3::Scope::Unchanged)), "S:U"),
(Metric::V3(v3::Metric::Scope(v3::Scope::Changed)), "S:C"),
(Metric::V3(v3::Metric::Confidentiality(v3::Impact::None)), "C:N"),
(Metric::V3(v3::Metric::Confidentiality(v3::Impact::Low)), "C:L"),
(Metric::V3(v3::Metric::Confidentiality(v3::Impact::High)), "C:H"),
(Metric::V3(v3::Metric::Integrity(v3::Impact::None)), "I:N"),
(Metric::V3(v3::Metric::Integrity(v3::Impact::Low)), "I:L"),
(Metric::V3(v3::Metric::Integrity(v3::Impact::High)), "I:H"),
(Metric::V3(v3::Metric::Availability(v3::Impact::None)), "A:N"),
(Metric::V3(v3::Metric::Availability(v3::Impact::Low)), "A:L"),
(Metric::V3(v3::Metric::Availability(v3::Impact::High)), "A:H"),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::Unproven)), "E:U"),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::ProofOfConcept)), "E:P"),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::Functional)), "E:F"),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::High)), "E:H"),
(Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::NotDefined)), "E:X"),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::OfficialFix)), "RL:O"),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::TemporaryFix)), "RL:T"),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::Workaround)), "RL:W"),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::Unavailable)), "RL:U"),
(Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::NotDefined)), "RL:X"),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Unknown)), "RC:U"),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Reasonable)), "RC:R"),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Confirmed)), "RC:C"),
(Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::NotDefined)), "RC:X"),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::Low)), "CR:L"),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::Medium)), "CR:M"),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::High)), "CR:H"),
(Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::NotDefined)), "CR:X"),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::Low)), "IR:L"),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::Medium)), "IR:M"),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::High)), "IR:H"),
(Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::NotDefined)), "IR:X"),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::Low)), "AR:L"),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::Medium)), "AR:M"),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::High)), "AR:H"),
(Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::NotDefined)), "AR:X"),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Network)), "MAV:N"),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Adjacent)), "MAV:A"),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Local)), "MAV:L"),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Physical)), "MAV:P"),
(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::NotDefined)), "MAV:X"),
(Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::High)), "MAC:H"),
(Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::Low)), "MAC:L"),
(Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::NotDefined)), "MAC:X"),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::High)), "MPR:H"),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::Low)), "MPR:L"),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::None)), "MPR:N"),
(Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::NotDefined)), "MPR:X"),
(Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::None)), "MUI:N"),
(Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::Required)), "MUI:R"),
(Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::NotDefined)), "MUI:X"),
(Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::Unchanged)), "MS:U"),
(Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::Changed)), "MS:C"),
(Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::NotDefined)), "MS:X"),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::None)), "MC:N"),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::Low)), "MC:L"),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::High)), "MC:H"),
(Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::NotDefined)), "MC:X"),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::None)), "MI:N"),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::Low)), "MI:L"),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::High)), "MI:H"),
(Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::NotDefined)), "MI:X"),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::None)), "MA:N"),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::Low)), "MA:L"),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::High)), "MA:H"),
(Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::NotDefined)), "MA:X"),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Network)), "AV:N"),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Adjacent)), "AV:A"),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Local)), "AV:L"),
(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Physical)), "AV:P"),
(Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::Low)), "AC:L"),
(Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::High)), "AC:H"),
(Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::None)), "AT:N"),
(Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::Present)), "AT:P"),
(Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::None)), "PR:N"),
(Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::Low)), "PR:L"),
(Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::High)), "PR:H"),
(Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::None)), "UI:N"),
(Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::Passive)), "UI:P"),
(Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::Active)), "UI:A"),
(Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::High)), "VC:H"),
(Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::Low)), "VC:L"),
(Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::None)), "VC:N"),
(Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::High)), "VI:H"),
(Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::Low)), "VI:L"),
(Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::None)), "VI:N"),
(Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::High)), "VA:H"),
(Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::Low)), "VA:L"),
(Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::None)), "VA:N"),
(Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::High)), "SC:H"),
(Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::Low)), "SC:L"),
(Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::None)), "SC:N"),
(Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::High)), "SI:H"),
(Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::Low)), "SI:L"),
(Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::None)), "SI:N"),
(Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::High)), "SA:H"),
(Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::Low)), "SA:L"),
(Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::None)), "SA:N"),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::NotDefined)), "E:X"),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::Attacked)), "E:A"),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::ProofOfConcept)), "E:P"),
(Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::Unreported)), "E:U"),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::NotDefined)), "CR:X"),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::High)), "CR:H"),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::Medium)), "CR:M"),
(Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::Low)), "CR:L"),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::NotDefined)), "IR:X"),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::High)), "IR:H"),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::Medium)), "IR:M"),
(Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::Low)), "IR:L"),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::NotDefined)), "AR:X"),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::High)), "AR:H"),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::Medium)), "AR:M"),
(Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::Low)), "AR:L"),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::NotDefined)), "MAV:X"),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Network)), "MAV:N"),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Adjacent)), "MAV:A"),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Local)), "MAV:L"),
(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Physical)), "MAV:P"),
(Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::NotDefined)), "MAC:X"),
(Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::Low)), "MAC:L"),
(Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::High)), "MAC:H"),
(Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::NotDefined)), "MAT:X"),
(Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::None)), "MAT:N"),
(Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::Present)), "MAT:P"),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::NotDefined)), "MPR:X"),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::None)), "MPR:N"),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::Low)), "MPR:L"),
(Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::High)), "MPR:H"),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::NotDefined)), "MUI:X"),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::None)), "MUI:N"),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::Passive)), "MUI:P"),
(Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::Active)), "MUI:A"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::NotDefined)), "MVC:X"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::High)), "MVC:H"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::Low)), "MVC:L"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::None)), "MVC:N"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::NotDefined)), "MVI:X"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::High)), "MVI:H"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::Low)), "MVI:L"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::None)), "MVI:N"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::NotDefined)), "MVA:X"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::High)), "MVA:H"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::Low)), "MVA:L"),
(Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::None)), "MVA:N"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::NotDefined)), "MSC:X"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::High)), "MSC:H"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::Low)), "MSC:L"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::None)), "MSC:N"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::NotDefined)), "MSI:X"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::High)), "MSI:H"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::Low)), "MSI:L"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::None)), "MSI:N"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::Safety)), "MSI:S"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::NotDefined)), "MSA:X"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::High)), "MSA:H"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::Low)), "MSA:L"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::None)), "MSA:N"),
(Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::Safety)), "MSA:S"),
(Metric::V4(v4::Metric::Safety(v4::Safety::NotDefined)), "S:X"),
(Metric::V4(v4::Metric::Safety(v4::Safety::Present)), "S:P"),
(Metric::V4(v4::Metric::Safety(v4::Safety::Negligible)), "S:N"),
(Metric::V4(v4::Metric::Automatable(v4::Automatable::NotDefined)), "AU:X"),
(Metric::V4(v4::Metric::Automatable(v4::Automatable::No)), "AU:N"),
(Metric::V4(v4::Metric::Automatable(v4::Automatable::Yes)), "AU:Y"),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::NotDefined)), "R:X"),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::Automatic)), "R:A"),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::User)), "R:U"),
(Metric::V4(v4::Metric::Recovery(v4::Recovery::Irrecoverable)), "R:I"),
(Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::NotDefined)), "V:X"),
(Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::Diffuse)), "V:D"),
(Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::Concentrated)), "V:C"),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::NotDefined)), "RE:X"),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::Low)), "RE:L"),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::Moderate)), "RE:M"),
(Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::High)), "RE:H"),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::NotDefined)), "U:X"),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Red)), "U:Red"),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Amber)), "U:Amber"),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Green)), "U:Green"),
(Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Clear)), "U:Clear"),
];
for (metric, exp) in tests {
assert_eq!(metric.to_string(), exp);
}
}
#[test]
fn test_size() {
assert_eq!(size_of::<Metric>(), 1 + size_of::<u16>());
}
}
mod vector {
use super::super::{Err, Metric, Name, Score, Vector, v2, v3, v4};
#[test]
fn test_from_str_fail() {
let tests = vec![
("empty", "", Err::Len),
];
for (name, s, exp) in tests {
assert_eq!(s.parse::<Vector>(), Err(exp), "{name}");
}
}
#[test]
fn test_from_str_pass() {
let tests = vec![
"AV:L/AC:L/Au:N/C:C/I:C/A:C", "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H", ];
for t in tests {
t.parse::<Vector>().expect(t);
}
}
#[test]
fn test_to_string() {
let tests = vec![
(
"v2-default", "AV:N/AC:L/Au:N/C:C/I:C/A:C", "AV:N/AC:L/Au:N/C:C/I:C/A:C", ),
(
"v2-everything", "AV:N/AC:L/Au:N/C:C/I:C/A:C/E:H/RL:U/RC:C/CDP:H/TD:H/CR:H/IR:H/AR:H", "AV:N/AC:L/Au:N/C:C/I:C/A:C/E:H/RL:U/RC:C/CDP:H/TD:H/CR:H/IR:H/AR:H", ),
(
"v3-default", "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", ),
(
"v3-everything", "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:C/C:N/I:N/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L/MAV:P/MAC:H/MPR:H/MUI:R/MS:C/MC:H/MI:H/MA:H", "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:C/C:N/I:N/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L/MAV:P/MAC:H/MPR:H/MUI:R/MS:C/MC:H/MI:H/MA:H", ),
(
"v4-default", "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H", "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H", ),
(
"v4-everything", "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:L/SC:L/SI:L/SA:L/E:A/CR:H/IR:H/AR:H/MAV:N/MAC:L/MAT:N/MPR:N/MUI:N/MVC:N/MVI:N/MVA:N/MSC:N/MSI:N/MSA:N/S:N/AU:N/R:A/V:D/RE:L/U:Clear", "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:L/SC:L/SI:L/SA:L/E:A/CR:H/IR:H/AR:H/MAV:N/MAC:L/MAT:N/MPR:N/MUI:N/MVC:N/MVI:N/MVA:N/MSC:N/MSI:N/MSA:N/S:N/AU:N/R:A/V:D/RE:L/U:Clear", ),
];
for (name, s, exp) in tests {
assert_eq!(s.parse::<Vector>().expect(name).to_string(), exp, "{name}");
}
}
#[test]
fn test_get() {
let tests = vec![(
"v2, base metric", "AV:N/AC:L/Au:N/C:C/I:C/A:C", Name::V2(v2::Name::AccessVector), Ok(Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network))), ), (
"v2, optional metric, not defined", "AV:N/AC:L/Au:N/C:C/I:C/A:C", Name::V2(v2::Name::Exploitability), Ok(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::NotDefined))), ), (
"v2, optional metric, defined", "AV:N/AC:L/Au:N/C:C/I:C/A:C/E:H", Name::V2(v2::Name::Exploitability), Ok(Metric::V2(v2::Metric::Exploitability(v2::Exploitability::High))), ), (
"v2, name mismatch", "AV:N/AC:L/Au:N/C:C/I:C/A:C/E:H", Name::V3(v3::Name::AttackVector), Err(Err::UnknownName), ), (
"v3, base metric", "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", Name::V3(v3::Name::AttackVector), Ok(Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Network))), ), (
"v3, optional metric, not defined", "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:C/C:N/I:N/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L", Name::V3(v3::Name::ModifiedAttackVector), Ok(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::NotDefined))), ), (
"v3, optional metric, defined", "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:C/C:N/I:N/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L/MAV:P/MAC:H/MPR:H/MUI:R/MS:C/MC:H/MI:H/MA:H", Name::V3(v3::Name::ModifiedAttackVector), Ok(Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Physical))), ), (
"v3, name mismatch", "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", Name::V4(v4::Name::AttackVector), Err(Err::UnknownName), ), (
"v4, base metric", "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H", Name::V4(v4::Name::AttackVector), Ok(Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Network))), ), (
"v4, optional metric, not defined", "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H", Name::V4(v4::Name::ModifiedAttackVector), Ok(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::NotDefined))), ), (
"v4, optional metric, defined", "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/MAV:A", Name::V4(v4::Name::ModifiedAttackVector), Ok(Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Adjacent))), ), (
"v4, name mismatch", "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/MAV:A", Name::V3(v3::Name::AttackVector), Err(Err::UnknownName), )];
for (test_name, s, metric_name, exp) in tests {
let v: Vector = s.parse().unwrap();
assert_eq!(v.get(metric_name), exp, "{test_name}");
}
}
#[test]
fn test_iter_explicit() {
let tests = vec![
(
"v2, basic",
"AV:N/AC:L/Au:N/C:C/I:C/A:C", vec![
Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network)),
Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Low)),
Metric::V2(v2::Metric::Authentication(v2::Authentication::None)),
Metric::V2(v2::Metric::Confidentiality(v2::Impact::Complete)),
Metric::V2(v2::Metric::Integrity(v2::Impact::Complete)),
Metric::V2(v2::Metric::Availability(v2::Impact::Complete)),
]
),
(
"v2, everything",
"AV:N/AC:L/Au:N/C:C/I:C/A:C/E:H/RL:U/RC:C/CDP:H/TD:H/CR:H/IR:H/AR:H", vec![
Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network)), Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Low)), Metric::V2(v2::Metric::Authentication(v2::Authentication::None)), Metric::V2(v2::Metric::Confidentiality(v2::Impact::Complete)), Metric::V2(v2::Metric::Integrity(v2::Impact::Complete)), Metric::V2(v2::Metric::Availability(v2::Impact::Complete)), Metric::V2(v2::Metric::Exploitability(v2::Exploitability::High)), Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::Unavailable)), Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Confirmed)), Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::High)), Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::High)), Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::High)), Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::High)), Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::High)), ]
),
(
"v3, basic",
"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
vec![
Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Network)),
Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::Low)),
Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::None)),
Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::None)),
Metric::V3(v3::Metric::Scope(v3::Scope::Unchanged)),
Metric::V3(v3::Metric::Confidentiality(v3::Impact::High)),
Metric::V3(v3::Metric::Integrity(v3::Impact::High)),
Metric::V3(v3::Metric::Availability(v3::Impact::High)),
]
),
(
"v3, everything",
"CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:C/C:N/I:N/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L/MAV:P/MAC:H/MPR:H/MUI:R/MS:C/MC:H/MI:H/MA:H",
vec![
Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Physical)),
Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::High)),
Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::High)),
Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::Required)),
Metric::V3(v3::Metric::Scope(v3::Scope::Changed)),
Metric::V3(v3::Metric::Confidentiality(v3::Impact::None)),
Metric::V3(v3::Metric::Integrity(v3::Impact::None)),
Metric::V3(v3::Metric::Availability(v3::Impact::None)),
Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::Unproven)),
Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::OfficialFix)),
Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Unknown)),
Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::Low)),
Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::Low)),
Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::Low)),
Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Physical)),
Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::High)),
Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::High)),
Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::Required)),
Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::Changed)),
Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::High)),
Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::High)),
Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::High)),
]
),
(
"v4, basic",
"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
vec![
Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Network)),
Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::Low)),
Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::None)),
Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::None)),
Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::None)),
Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::High)),
]
),
(
"v4, everything",
"CVSS:4.0/AV:P/AC:H/AT:P/PR:H/UI:A/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:A/CR:H/IR:H/AR:H/MAV:P/MAC:H/MAT:P/MPR:H/MUI:A/MVC:N/MVI:N/MVA:N/MSC:N/MSI:S/MSA:S/S:N/AU:Y/R:I/V:C/RE:H/U:Clear",
vec![
Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Physical)),
Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::High)),
Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::Present)),
Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::High)),
Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::Active)),
Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::Attacked)),
Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::High)),
Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::High)),
Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::High)),
Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Physical)),
Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::High)),
Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::Present)),
Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::High)),
Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::Active)),
Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::Safety)),
Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::Safety)),
Metric::V4(v4::Metric::Safety(v4::Safety::Negligible)),
Metric::V4(v4::Metric::Automatable(v4::Automatable::Yes)),
Metric::V4(v4::Metric::Recovery(v4::Recovery::Irrecoverable)),
Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::Concentrated)),
Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::High)),
Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Clear)),
]
),
];
for (name, s, exp) in tests {
let got: Vec<Metric> = s.parse::<Vector>().unwrap().into_iter().collect();
assert_eq!(got, exp, "{name}");
}
}
#[test]
fn test_iter_implicit() {
let tests = vec![
(
"v2, basic",
"AV:N/AC:L/Au:N/C:C/I:C/A:C", vec![
Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network)),
Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Low)),
Metric::V2(v2::Metric::Authentication(v2::Authentication::None)),
Metric::V2(v2::Metric::Confidentiality(v2::Impact::Complete)),
Metric::V2(v2::Metric::Integrity(v2::Impact::Complete)),
Metric::V2(v2::Metric::Availability(v2::Impact::Complete)),
]
),
(
"v2, everything",
"AV:N/AC:L/Au:N/C:C/I:C/A:C/E:H/RL:U/RC:C/CDP:H/TD:H/CR:H/IR:H/AR:H", vec![
Metric::V2(v2::Metric::AccessVector(v2::AccessVector::Network)), Metric::V2(v2::Metric::AccessComplexity(v2::AccessComplexity::Low)), Metric::V2(v2::Metric::Authentication(v2::Authentication::None)), Metric::V2(v2::Metric::Confidentiality(v2::Impact::Complete)), Metric::V2(v2::Metric::Integrity(v2::Impact::Complete)), Metric::V2(v2::Metric::Availability(v2::Impact::Complete)), Metric::V2(v2::Metric::Exploitability(v2::Exploitability::High)), Metric::V2(v2::Metric::RemediationLevel(v2::RemediationLevel::Unavailable)), Metric::V2(v2::Metric::ReportConfidence(v2::ReportConfidence::Confirmed)), Metric::V2(v2::Metric::CollateralDamagePotential(v2::CollateralDamagePotential::High)), Metric::V2(v2::Metric::TargetDistribution(v2::TargetDistribution::High)), Metric::V2(v2::Metric::ConfidentialityRequirement(v2::Requirement::High)), Metric::V2(v2::Metric::IntegrityRequirement(v2::Requirement::High)), Metric::V2(v2::Metric::AvailabilityRequirement(v2::Requirement::High)), ]
),
(
"v3, basic",
"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
vec![
Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Network)),
Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::Low)),
Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::None)),
Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::None)),
Metric::V3(v3::Metric::Scope(v3::Scope::Unchanged)),
Metric::V3(v3::Metric::Confidentiality(v3::Impact::High)),
Metric::V3(v3::Metric::Integrity(v3::Impact::High)),
Metric::V3(v3::Metric::Availability(v3::Impact::High)),
]
),
(
"v3, everything",
"CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:C/C:N/I:N/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L/MAV:P/MAC:H/MPR:H/MUI:R/MS:C/MC:H/MI:H/MA:H",
vec![
Metric::V3(v3::Metric::AttackVector(v3::AttackVector::Physical)),
Metric::V3(v3::Metric::AttackComplexity(v3::AttackComplexity::High)),
Metric::V3(v3::Metric::PrivilegesRequired(v3::PrivilegesRequired::High)),
Metric::V3(v3::Metric::UserInteraction(v3::UserInteraction::Required)),
Metric::V3(v3::Metric::Scope(v3::Scope::Changed)),
Metric::V3(v3::Metric::Confidentiality(v3::Impact::None)),
Metric::V3(v3::Metric::Integrity(v3::Impact::None)),
Metric::V3(v3::Metric::Availability(v3::Impact::None)),
Metric::V3(v3::Metric::ExploitCodeMaturity(v3::ExploitCodeMaturity::Unproven)),
Metric::V3(v3::Metric::RemediationLevel(v3::RemediationLevel::OfficialFix)),
Metric::V3(v3::Metric::ReportConfidence(v3::ReportConfidence::Unknown)),
Metric::V3(v3::Metric::ConfidentialityRequirement(v3::Requirement::Low)),
Metric::V3(v3::Metric::IntegrityRequirement(v3::Requirement::Low)),
Metric::V3(v3::Metric::AvailabilityRequirement(v3::Requirement::Low)),
Metric::V3(v3::Metric::ModifiedAttackVector(v3::ModifiedAttackVector::Physical)),
Metric::V3(v3::Metric::ModifiedAttackComplexity(v3::ModifiedAttackComplexity::High)),
Metric::V3(v3::Metric::ModifiedPrivilegesRequired(v3::ModifiedPrivilegesRequired::High)),
Metric::V3(v3::Metric::ModifiedUserInteraction(v3::ModifiedUserInteraction::Required)),
Metric::V3(v3::Metric::ModifiedScope(v3::ModifiedScope::Changed)),
Metric::V3(v3::Metric::ModifiedConfidentiality(v3::ModifiedImpact::High)),
Metric::V3(v3::Metric::ModifiedIntegrity(v3::ModifiedImpact::High)),
Metric::V3(v3::Metric::ModifiedAvailability(v3::ModifiedImpact::High)),
]
),
(
"v4, basic",
"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
vec![
Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Network)),
Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::Low)),
Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::None)),
Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::None)),
Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::None)),
Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::High)),
]
),
(
"v4, everything",
"CVSS:4.0/AV:P/AC:H/AT:P/PR:H/UI:A/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:A/CR:H/IR:H/AR:H/MAV:P/MAC:H/MAT:P/MPR:H/MUI:A/MVC:N/MVI:N/MVA:N/MSC:N/MSI:S/MSA:S/S:N/AU:Y/R:I/V:C/RE:H/U:Clear",
vec![
Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Physical)),
Metric::V4(v4::Metric::AttackComplexity(v4::AttackComplexity::High)),
Metric::V4(v4::Metric::AttackRequirements(v4::AttackRequirements::Present)),
Metric::V4(v4::Metric::PrivilegesRequired(v4::PrivilegesRequired::High)),
Metric::V4(v4::Metric::UserInteraction(v4::UserInteraction::Active)),
Metric::V4(v4::Metric::VulnerableSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::VulnerableSystemAvailabilityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemConfidentialityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemIntegrityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::SubsequentSystemAvailabilityImpact(v4::Impact::High)),
Metric::V4(v4::Metric::ExploitMaturity(v4::ExploitMaturity::Attacked)),
Metric::V4(v4::Metric::ConfidentialityRequirement(v4::Requirement::High)),
Metric::V4(v4::Metric::IntegrityRequirement(v4::Requirement::High)),
Metric::V4(v4::Metric::AvailabilityRequirement(v4::Requirement::High)),
Metric::V4(v4::Metric::ModifiedAttackVector(v4::ModifiedAttackVector::Physical)),
Metric::V4(v4::Metric::ModifiedAttackComplexity(v4::ModifiedAttackComplexity::High)),
Metric::V4(v4::Metric::ModifiedAttackRequirements(v4::ModifiedAttackRequirements::Present)),
Metric::V4(v4::Metric::ModifiedPrivilegesRequired(v4::ModifiedPrivilegesRequired::High)),
Metric::V4(v4::Metric::ModifiedUserInteraction(v4::ModifiedUserInteraction::Active)),
Metric::V4(v4::Metric::ModifiedVulnerableSystemConfidentiality(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedVulnerableSystemIntegrity(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedVulnerableSystemAvailability(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedSubsequentSystemConfidentiality(v4::ModifiedImpact::None)),
Metric::V4(v4::Metric::ModifiedSubsequentSystemIntegrity(v4::ModifiedSubsequentImpact::Safety)),
Metric::V4(v4::Metric::ModifiedSubsequentSystemAvailability(v4::ModifiedSubsequentImpact::Safety)),
Metric::V4(v4::Metric::Safety(v4::Safety::Negligible)),
Metric::V4(v4::Metric::Automatable(v4::Automatable::Yes)),
Metric::V4(v4::Metric::Recovery(v4::Recovery::Irrecoverable)),
Metric::V4(v4::Metric::ValueDensity(v4::ValueDensity::Concentrated)),
Metric::V4(v4::Metric::VulnerabilityResponseEffort(v4::VulnerabilityResponseEffort::High)),
Metric::V4(v4::Metric::ProviderUrgency(v4::ProviderUrgency::Clear)),
]
),
];
for (name, s, exp) in tests {
let mut got: Vec<Metric> = Vec::new();
for c in s.parse::<Vector>().unwrap() {
got.push(c);
}
assert_eq!(got, exp, "{name}");
}
}
#[test]
fn test_base_score() {
let tests = vec![(
"v2", "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:F/RL:OF/RC:C/CDP:N/TD:N/CR:M/IR:M/AR:H", Score(78), ), (
"v3", "CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L/E:P/RL:U/RC:C/CR:L/IR:X/AR:M/MAV:N/MAC:H/MPR:X/MUI:X/MS:U/MC:L/MI:N/MA:H", Score(43), ), (
"v4", "CVSS:4.0/AV:P/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:H/SI:L/SA:L/E:P/CR:X/IR:X/AR:X/MAV:N/MAC:X/MAT:N/MPR:H/MUI:X/MVC:N/MVI:N/MVA:N/MSC:L/MSI:X/MSA:X", Score(19), )];
for (name, s, exp) in tests {
let vec: Vector = s.parse().unwrap();
assert_eq!(vec.base_score(), exp, "{name}");
}
}
#[test]
fn test_size() {
assert_eq!(size_of::<Vector>(), size_of::<u64>());
}
}
mod score {
use {std::cmp::Ordering, super::super::Score};
#[test]
fn test_from_f32() {
let tests = vec![
(1.2_f32, Score(12)),
(5.23_f32, Score(52)),
(-1_f32, Score(0)), (12345_f32, Score(100)), ];
for (val, exp) in tests {
assert_eq!(Score::from(val), exp, "{val}");
}
}
#[test]
fn test_from_f64() {
let tests = vec![
(1.2_f64, Score(12)),
(5.23_f64, Score(52)),
(-1_f64, Score(0)), (12345_f64, Score(100)), ];
for (val, exp) in tests {
assert_eq!(Score::from(val), exp, "{val}");
}
}
#[test]
fn test_to_string() {
let tests = vec![
(Score(93), "9.3"),
(Score(52), "5.2"),
(Score(63), "6.3"),
];
for (score, exp) in tests {
assert_eq!(score.to_string(), exp, "{exp}");
}
}
#[test]
fn test_cmp() {
let tests = vec![
(Score(10), Score(20), Ordering::Less),
(Score(10), Score(10), Ordering::Equal),
(Score(30), Score(20), Ordering::Greater),
];
for (a, b, exp) in tests {
assert_eq!(a.cmp(&b), exp);
}
}
#[test]
fn test_lt() {
let tests = vec![
(Score(10), Score(20), true),
(Score(10), Score(10), false),
(Score(30), Score(20), false),
];
for (a, b, exp) in tests {
assert_eq!(a < b, exp);
}
}
#[test]
fn test_add() {
let tests = vec![
(Score(10), Score(20), Score(30)),
(Score(90), Score(20), Score(100)), ];
for (a, b, exp) in tests {
assert_eq!(a + b, exp, "{a} + {b}");
}
}
#[test]
fn test_from_vector() {
use super::super::Vector;
let tests = vec![(
"v2", "AV:L/AC:H/Au:N/C:C/I:C/A:C/E:POC/RL:OF/RC:C/CDP:H/TD:H/CR:M/IR:M/AR:M", Score(74), ), (
"v3", "CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L/E:P/RL:U/RC:C/CR:L/IR:X/AR:M/MAV:N/MAC:H/MPR:X/MUI:X/MS:U/MC:L/MI:N/MA:H", Score(59), ), (
"v4", "CVSS:4.0/AV:P/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:H/SI:L/SA:L/E:P/CR:X/IR:X/AR:X/MAV:N/MAC:X/MAT:N/MPR:H/MUI:X/MVC:N/MVI:N/MVA:N/MSC:L/MSI:X/MSA:X", Score(19), )];
for (name, s, exp) in tests {
let vec: Vector = s.parse().unwrap();
assert_eq!(Score::from(vec), exp, "{name}");
}
}
}
mod severity {
use super::super::{Err, Score, Severity, Vector};
#[test]
fn test_from_str_fail() {
let tests = vec![
"asdf",
];
for t in tests {
assert_eq!(t.parse::<Severity>(), Err(Err::UnknownSeverity), "{t}");
}
}
#[test]
fn test_from_str_pass() {
let tests = vec![
("NONE", Severity::None),
("LOW", Severity::Low),
("MEDIUM", Severity::Medium),
("HIGH", Severity::High),
("CRITICAL", Severity::Critical),
];
for (s, exp) in tests {
assert_eq!(s.parse::<Severity>().unwrap(), exp, "{s}");
}
}
#[test]
fn test_to_string() {
let tests = vec![
(Severity::None, "NONE"),
(Severity::Low, "LOW"),
(Severity::Medium, "MEDIUM"),
(Severity::High, "HIGH"),
(Severity::Critical, "CRITICAL"),
];
for (s, exp) in tests {
assert_eq!(s.to_string(), exp, "{s}");
}
}
#[test]
fn test_from_score() {
let tests = vec![
(Score(0), Severity::None),
(Score(1), Severity::Low),
(Score(39), Severity::Low),
(Score(40), Severity::Medium),
(Score(69), Severity::Medium),
(Score(70), Severity::High),
(Score(89), Severity::High),
(Score(90), Severity::Critical),
(Score(100), Severity::Critical),
];
for (score, exp) in tests {
assert_eq!(Severity::from(score), exp, "{score}");
}
}
#[test]
fn test_from_vector() {
let tests = vec![
("AV:A/AC:H/Au:N/C:C/I:C/A:C", Severity::Medium),
("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", Severity::Critical),
("CVSS:4.0/AV:L/AC:H/AT:N/PR:N/UI:P/VC:H/VI:L/VA:L/SC:H/SI:H/SA:H", Severity::High),
];
for (s, exp) in tests {
let vec: Vector = s.parse().unwrap();
assert_eq!(Severity::from(vec), exp, "{exp}");
}
}
#[test]
fn test_cmp() {
use std::cmp::Ordering;
let tests = vec![
(Severity::None, Severity::None, Ordering::Equal),
(Severity::None, Severity::Low, Ordering::Less),
(Severity::High, Severity::Medium, Ordering::Greater),
];
for (a, b, exp) in tests {
assert_eq!(a.cmp(&b), exp, "{a},{b}");
}
}
}
}