Skip to content

Commit

Permalink
Added test 6.1.25
Browse files Browse the repository at this point in the history
  • Loading branch information
oxisto committed Nov 8, 2024
1 parent 8220037 commit 5ad2ba4
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ sealed interface Profile {
* Base](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#41-profile-1-csaf-base).
*/
object CSAFBase : Profile {
override val category = null
override val category = "csaf_base"
}

/**
Expand Down Expand Up @@ -67,7 +67,7 @@ object VEX : Profile {

/** List of defined "official" profiles. */
val officialProfiles =
mapOf<String?, Profile>(
mapOf<String, Profile>(
CSAFBase.category to CSAFBase,
SecurityIncidentResponse.category to SecurityIncidentResponse,
InformationalAdvisory.category to InformationalAdvisory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fun Csaf.gatherProductDefinitions(): List<String> {
*/
fun Csaf.Branche.gatherProductURLs(products: MutableCollection<String>) {
// Add ID at this leaf
products += product?.product_identification_helper?.purl.toString()
products += product?.product_identification_helper?.purl?.toString()

// Go down the branch
this.branches?.forEach { it.gatherProductURLs(products) }
Expand All @@ -81,13 +81,13 @@ fun Csaf.gatherProductURLs(): MutableList<String> {
// /product_tree/full_product_names[]/product_identification_helper/purl
purls +=
this.product_tree?.full_product_names?.mapNotNull {
it.product_identification_helper?.purl.toString()
it.product_identification_helper?.purl?.toString()
}

// /product_tree/relationships[]/full_product_name/product_identification_helper/purl
purls +=
this.product_tree?.relationships?.map {
it.full_product_name.product_identification_helper?.purl.toString()
this.product_tree?.relationships?.mapNotNull {
it.full_product_name.product_identification_helper?.purl?.toString()
}

return purls
Expand Down Expand Up @@ -176,6 +176,36 @@ fun Csaf.gatherProductGroupReferences(): Set<String> {
return ids
}

fun Csaf.Branche.gatherFileHashLists(lists: MutableCollection<List<Csaf.FileHashe>>) {
// Add file hashes at this leaf
lists += this.product?.product_identification_helper?.hashes?.map { it.file_hashes }

// Go down the branch
this.branches?.forEach { it.gatherFileHashLists(lists) }
}

fun Csaf.gatherFileHashLists(): MutableList<List<Csaf.FileHashe>> {
var lists = mutableListOf<List<Csaf.FileHashe>>()

// /product_tree/branches[](/branches[])*/product/product_identification_helper/hashes[]/file_hashes
this.product_tree?.branches?.forEach { it.gatherFileHashLists(lists) }

// /product_tree/full_product_names[]/product_identification_helper/hashes[]/file_hashes
lists +=
this.product_tree?.full_product_names?.flatMap {
it.product_identification_helper?.hashes?.map { it.file_hashes } ?: listOf()
}

// /product_tree/relationships[]/full_product_name/product_identification_helper/hashes[]/file_hashes
lists +=
this.product_tree?.relationships?.flatMap {
it.full_product_name.product_identification_helper?.hashes?.map { it.file_hashes }
?: listOf()
}

return lists
}

/**
* Returns the profile according to
* [Section 4](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#4-profiles). If this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import io.github.csaf.sbom.validation.profiles.InformationalAdvisory
import io.github.csaf.sbom.validation.profiles.SecurityAdvisory
import io.github.csaf.sbom.validation.profiles.SecurityIncidentResponse
import io.github.csaf.sbom.validation.profiles.VEX
import io.github.csaf.sbom.validation.profiles.officialProfiles
import kotlin.collections.flatMap
import kotlin.reflect.KProperty1
import net.swiftzer.semver.SemVer
Expand Down Expand Up @@ -65,6 +66,8 @@ val mandatoryTests =
Test6122MultipleDefinitionInRevisionHistory,
Test6123MultipleUseOfSameCVE,
Test6124MultipleDefinitionInInvolvements,
Test6125MultipleUseOfSameHashAlgorithm,
Test6126ProhibitedDocumentCategoryName,
Test61271DocumentNotes,
Test61272DocumentReferences,
Test61273Vulnerabilities,
Expand Down Expand Up @@ -793,6 +796,52 @@ object Test6124MultipleDefinitionInInvolvements : Test {
}
}

/**
* Implementation of
* [Test 6.1.25](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#6125-multiple-use-of-same-hash-algorithm).
*/
object Test6125MultipleUseOfSameHashAlgorithm : Test {
override fun test(doc: Csaf): ValidationResult {
var hashLists = doc.gatherFileHashLists()
var duplicates = hashLists.flatMap { it.map { it.algorithm }.duplicates().keys }

return if (duplicates.isEmpty()) {
ValidationSuccessful
} else {
return ValidationFailed(
listOf(
"The following hash algorithms are duplicate: ${duplicates.joinToString(", ")}"
)
)
}
}
}

/**
* Implementation of
* [Test 6.1.26](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#6126-prohibited-document-category-name).
*/
object Test6126ProhibitedDocumentCategoryName : Test {
override fun test(doc: Csaf): ValidationResult {
if (doc.document.category in officialProfiles.keys) {
return ValidationNotApplicable
}

val cleanedCategory = doc.document.category.lowercase().replace("(_-)", "")

// It is not allowed to match an official profile's name (without csaf_ prefix)
return if (cleanedCategory !in officialProfiles.keys.map { it.substringAfter("csaf_") }) {
ValidationSuccessful
} else {
ValidationFailed(
listOf(
"The value $cleanedCategory is the name of a profile where the space was replaced with underscores"
)
)
}
}
}

/**
* Implementation of
* [Test 6.1.27.1](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#61271-document-notes).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,28 @@ class TestsTest {
assertValidationSuccessful(test.test(goodCsaf(vulnerabilities = null)))
}

@Test
fun test6125() {
val test = Test6125MultipleUseOfSameHashAlgorithm

// failing examples
assertValidationFailed(
"The following hash algorithms are duplicate: sha256",
test.test(mandatoryTest("6-1-25-01"))
)
}

@Test
fun test6126() {
val test = Test6126ProhibitedDocumentCategoryName

// failing examples
assertValidationFailed(
"The value security_incident_response is the name of a profile where the space was replaced with underscores",
test.test(mandatoryTest("6-1-26-01"))
)
}

@Test
fun test61271() {
val test = Test61271DocumentNotes
Expand Down

0 comments on commit 5ad2ba4

Please sign in to comment.