Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions csaf-lib/src/csaf/csaf2_0/getter_implementations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use crate::csaf::csaf2_0::schema::{CategoryOfTheRemediation, CommonSecurityAdvisoryFramework, ProductGroup, ProductTree, Remediation, Vulnerability};
use crate::csaf::csaf2_1::schema::CategoryOfTheRemediation as Remediation21;
use crate::csaf::getter_traits::{CsafTrait, ProductGroupTrait, ProductTreeTrait, RemediationTrait, VulnerabilityTrait};
use std::ops::Deref;

impl RemediationTrait for Remediation {

/// Normalizes the remediation categories from CSAF 2.0 to those of CSAF 2.1.
///
/// # Explanation
/// In CSAF 2.1, the list of remediation categories was expanded, making it a superset of those
/// in CSAF 2.0. This function ensures that the remediation category from a CSAF 2.0 remediation
/// object is converted into the corresponding category defined in CSAF 2.1.
///
/// # Returns
/// A CSAF 2.1 `CategoryOfTheRemediation` that corresponds to the remediation category of the
/// current object.
fn get_category(&self) -> Remediation21 {
match self.category {
CategoryOfTheRemediation::Workaround => Remediation21::Workaround,
CategoryOfTheRemediation::Mitigation => Remediation21::Mitigation,
CategoryOfTheRemediation::VendorFix => Remediation21::VendorFix,
CategoryOfTheRemediation::NoFixPlanned => Remediation21::NoFixPlanned,
CategoryOfTheRemediation::NoneAvailable => Remediation21::NoneAvailable,
}
}

fn get_product_ids(&self) -> Option<Vec<&String>> {
self.product_ids.as_ref().map(|p| (*p).iter().map(|x| x.deref()).collect())
}

fn get_group_ids(&self) -> Option<Vec<&String>> {
self.group_ids.as_ref().map(|g| (*g).iter().map(|x| x.deref()).collect())
}
}

impl VulnerabilityTrait for Vulnerability {
type RemediationType = Remediation;

fn get_remediations(&self) -> Vec<Self::RemediationType> {
self.remediations.clone()
}
}

impl CsafTrait for CommonSecurityAdvisoryFramework {
type VulnerabilityType = Vulnerability;
type ProductTreeType = ProductTree;

fn get_product_tree(&self) -> Option<Self::ProductTreeType> {
self.product_tree.clone()
}

fn get_vulnerabilities(&self) -> Vec<Self::VulnerabilityType> {
self.vulnerabilities.clone()
}
}

impl ProductTreeTrait for ProductTree {
type ProductGroupType = ProductGroup;

fn get_product_groups(&self) -> Vec<Self::ProductGroupType> {
self.product_groups.clone()
}
}

impl ProductGroupTrait for ProductGroup {
fn get_group_id(&self) -> &String {
self.group_id.deref()
}

fn get_product_ids(&self) -> Vec<&String> {
self.product_ids.iter().map(|x| x.deref()).collect()
}
}
1 change: 1 addition & 0 deletions csaf-lib/src/csaf/csaf2_0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod loader;
mod product_helper;
pub mod schema;
pub mod validation;
pub mod getter_implementations;
22 changes: 14 additions & 8 deletions csaf-lib/src/csaf/csaf2_0/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,25 @@ use crate::csaf::helpers::find_duplicates;

impl Validatable<CommonSecurityAdvisoryFramework> for CommonSecurityAdvisoryFramework {
fn presets(&self) -> HashMap<ValidationPreset, Vec<&str>> {
let basic_tests = Vec::from(["6.1.1", "6.1.2"]);
// More tests may be added in extend() here later
let extended_tests: Vec<&str> = basic_tests.clone();
// extended_tests.extend(["foo"].iter());
let full_tests: Vec<&str> = extended_tests.clone();
// full_tests.extend(["bar"].iter());
HashMap::from([
(ValidationPreset::Basic, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Extended, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Full, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Basic, basic_tests),
(ValidationPreset::Extended, extended_tests),
(ValidationPreset::Full, full_tests),
])
}

fn tests(&self) -> HashMap<&str, Test<CommonSecurityAdvisoryFramework>> {
HashMap::<&str, Test<CommonSecurityAdvisoryFramework>>::from([
("6.1.1", test_6_01_01_missing_definition_of_product_id),
("6.1.2", test_6_01_02_multiple_definition_of_product_id),
]
as [(&str, Test<CommonSecurityAdvisoryFramework>); 2])
type CsafTest = Test<CommonSecurityAdvisoryFramework>;
HashMap::from([
("6.1.1", test_6_01_01_missing_definition_of_product_id as CsafTest),
("6.1.2", test_6_01_02_multiple_definition_of_product_id as CsafTest),
])
}

fn doc(&self) -> &CommonSecurityAdvisoryFramework {
Expand Down
53 changes: 46 additions & 7 deletions csaf-lib/src/csaf/csaf2_1/csaf_json_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,20 @@
"minLength": 1
}
},
"purl": {
"title": "package URL representation",
"description": "The package URL (purl) attribute refers to a method for reliably identifying and locating software packages external to this specification.",
"type": "string",
"format": "uri",
"pattern": "^pkg:[A-Za-z\\.\\-\\+][A-Za-z0-9\\.\\-\\+]*\\/.+",
"minLength": 7
"purls": {
"title": "List of package URLs",
"description": "Contains a list of package URLs (purl).",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"title": "package URL representation",
"description": "The package URL (purl) attribute refers to a method for reliably identifying and locating software packages external to this specification.",
"type": "string",
"format": "uri",
"pattern": "^pkg:[A-Za-z\\.\\-\\+][A-Za-z0-9\\.\\-\\+]*\\/.+",
"minLength": 7
}
},
"sbom_urls": {
"title": "List of SBOM URLs",
Expand Down Expand Up @@ -581,6 +588,36 @@
"tlp"
],
"properties": {
"sharing_group": {
"title": "Sharing Group",
"description": "Contains information about the group this document is intended to be shared with.",
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"title": "Sharing Group ID",
"description": "Provides the unique ID for the sharing group.",
"type": "string",
"pattern": "^(([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12})|([0]{8}-([0]{4}-){3}[0]{12})|([f]{8}-([f]{4}-){3}[f]{12}))$"
},
"name": {
"title": "Sharing Group Name",
"description": "Contains a human-readable name for the sharing group.",
"type": "string",
"minLength": 1,
"examples": [
"Customer A",
"ISAC members",
"NIS2 regulated important entities in Germany, sector water",
"Pre-Sharing group for advisory discussion",
"Users of Product A",
"US Federal Civilian Authorities"
]
}
}
},
"text": {
"title": "Textual description",
"description": "Provides a textual description of additional constraints.",
Expand Down Expand Up @@ -1328,9 +1365,11 @@
"description": "Specifies the category which this remediation belongs to.",
"type": "string",
"enum": [
"fix_planned",
"mitigation",
"no_fix_planned",
"none_available",
"optional_patch",
"vendor_fix",
"workaround"
]
Expand Down
57 changes: 57 additions & 0 deletions csaf-lib/src/csaf/csaf2_1/getter_implementations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use crate::csaf::csaf2_1::schema::ProductTree;
use crate::csaf::csaf2_1::schema::{CategoryOfTheRemediation, CommonSecurityAdvisoryFramework, ProductGroup, Remediation, Vulnerability};
use crate::csaf::getter_traits::{CsafTrait, ProductGroupTrait, ProductTreeTrait, RemediationTrait, VulnerabilityTrait};
use std::ops::Deref;

impl RemediationTrait for Remediation {
fn get_category(&self) -> CategoryOfTheRemediation {
self.category.clone()
}

fn get_product_ids(&self) -> Option<Vec<&String>> {
self.product_ids.as_ref().map(|p| (*p).iter().map(|x| x.deref()).collect())
}

fn get_group_ids(&self) -> Option<Vec<&String>> {
self.group_ids.as_ref().map(|g| (*g).iter().map(|x| x.deref()).collect())
}
}

impl VulnerabilityTrait for Vulnerability {
type RemediationType = Remediation;

fn get_remediations(&self) -> Vec<Self::RemediationType> {
self.remediations.clone()
}
}

impl CsafTrait for CommonSecurityAdvisoryFramework {
type VulnerabilityType = Vulnerability;
type ProductTreeType = ProductTree;

fn get_product_tree(&self) -> Option<Self::ProductTreeType> {
self.product_tree.clone()
}

fn get_vulnerabilities(&self) -> Vec<Self::VulnerabilityType> {
self.vulnerabilities.clone()
}
}

impl ProductTreeTrait for ProductTree {
type ProductGroupType = ProductGroup;

fn get_product_groups(&self) -> Vec<Self::ProductGroupType> {
self.product_groups.clone()
}
}

impl ProductGroupTrait for ProductGroup {
fn get_group_id(&self) -> &String {
self.group_id.deref()
}

fn get_product_ids(&self) -> Vec<&String> {
self.product_ids.iter().map(|x| x.deref()).collect()
}
}
1 change: 1 addition & 0 deletions csaf-lib/src/csaf/csaf2_1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod loader;
mod product_helper;
pub mod schema;
pub mod validation;
pub mod getter_implementations;
Loading