Skip to content

Commit 316bced

Browse files
feat: add mandatory test 6.1.46
1 parent 908c3ae commit 316bced

File tree

4 files changed

+93
-1
lines changed

4 files changed

+93
-1
lines changed

csaf_2_1/mandatoryTests.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,5 @@ export { mandatoryTest_6_1_40 } from './mandatoryTests/mandatoryTest_6_1_40.js'
5959
export { mandatoryTest_6_1_41 } from './mandatoryTests/mandatoryTest_6_1_41.js'
6060
export { mandatoryTest_6_1_43 } from './mandatoryTests/mandatoryTest_6_1_43.js'
6161
export { mandatoryTest_6_1_45 } from './mandatoryTests/mandatoryTest_6_1_45.js'
62+
export { mandatoryTest_6_1_46 } from './mandatoryTests/mandatoryTest_6_1_46.js'
6263
export { mandatoryTest_6_1_52 } from './mandatoryTests/mandatoryTest_6_1_52.js'
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import Ajv from 'ajv/dist/jtd.js'
2+
import csafAjv from '../../lib/shared/csafAjv.js'
3+
4+
const ajv = new Ajv()
5+
6+
/*
7+
This is the jtd schema that needs to match the input document so that the
8+
test is activated. If this schema doesn't match it normally means that the input
9+
document does not validate against the csaf json schema or optional fields that
10+
the test checks are not present.
11+
*/
12+
const inputSchema = /** @type {const} */ ({
13+
additionalProperties: true,
14+
properties: {
15+
vulnerabilities: {
16+
elements: {
17+
additionalProperties: true,
18+
optionalProperties: {
19+
metrics: {
20+
elements: {
21+
additionalProperties: true,
22+
optionalProperties: {
23+
content: {
24+
additionalProperties: true,
25+
properties: {
26+
ssvc_v1: {
27+
additionalProperties: true,
28+
properties: {},
29+
},
30+
},
31+
},
32+
},
33+
},
34+
},
35+
},
36+
},
37+
},
38+
},
39+
})
40+
41+
const validateInput = ajv.compile(inputSchema)
42+
43+
const validate_ssvc_v1 = csafAjv.compile({
44+
$ref: 'https://certcc.github.io/SSVC/data/schema/v1/Decision_Point_Value_Selection-1-0-1.schema.json',
45+
})
46+
47+
/**
48+
* This implements the mandatory test 6.1.46 of the CSAF 2.1 standard.
49+
*
50+
* @param {unknown} doc
51+
*/
52+
export function mandatoryTest_6_1_46(doc) {
53+
/*
54+
The `ctx` variable holds the state that is accumulated during the test ran and is
55+
finally returned by the function.
56+
*/
57+
const ctx = {
58+
errors:
59+
/** @type {Array<{ instancePath: string; message: string }>} */ ([]),
60+
isValid: true,
61+
}
62+
63+
if (!validateInput(doc)) {
64+
return ctx
65+
}
66+
67+
doc.vulnerabilities?.forEach((vulnerability, vulnerabilityIndex) => {
68+
vulnerability.metrics?.forEach((metric, metricIndex) => {
69+
const valid = validate_ssvc_v1(metric.content?.ssvc_v1)
70+
if (!valid) {
71+
ctx.isValid = false
72+
for (const err of validate_ssvc_v1.errors ?? []) {
73+
ctx.errors.push({
74+
instancePath: `/vulnerabilities/${vulnerabilityIndex}/metrics/${metricIndex}/content/ssvc_v1${err.instancePath}`,
75+
message: err.message ?? '',
76+
})
77+
}
78+
}
79+
})
80+
})
81+
82+
return ctx
83+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import assert from 'node:assert/strict'
2+
import { mandatoryTest_6_1_46 } from '../../csaf_2_1/mandatoryTests/mandatoryTest_6_1_46.js'
3+
4+
describe('mandatoryTest_6_1_46', function () {
5+
it('only runs on relevant documents', function () {
6+
assert.equal(mandatoryTest_6_1_46({ document: 'mydoc' }).isValid, true)
7+
})
8+
})

tests/csaf_2_1/oasis.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const excluded = [
2222
'6.1.37',
2323
'6.1.42',
2424
'6.1.44',
25-
'6.1.46',
25+
'6.1.45',
2626
'6.1.47',
2727
'6.1.48',
2828
'6.1.49',

0 commit comments

Comments
 (0)