Skip to content

Commit 849c7a4

Browse files
committed
feat: add support for component's evidences according to spec
Signed-off-by: Arun <[email protected]>
1 parent cb1a359 commit 849c7a4

15 files changed

+1729
-32
lines changed

cyclonedx/model/component.py

Lines changed: 713 additions & 32 deletions
Large diffs are not rendered by default.

tests/_data/models.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import base64
1919
import sys
20+
from collections.abc import Iterable
2021
from datetime import datetime, timezone
2122
from decimal import Decimal
2223
from inspect import getmembers, isfunction
@@ -44,16 +45,23 @@
4445
from cyclonedx.model.bom import Bom, BomMetaData
4546
from cyclonedx.model.bom_ref import BomRef
4647
from cyclonedx.model.component import (
48+
AnalysisTechnique,
49+
CallStack,
4750
Commit,
4851
Component,
4952
ComponentEvidence,
5053
ComponentScope,
5154
ComponentType,
5255
Diff,
56+
Identity,
57+
IdentityFieldType,
58+
Method,
59+
Occurrence,
5360
OmniborId,
5461
Patch,
5562
PatchClassification,
5663
Pedigree,
64+
StackFrame,
5765
Swhid,
5866
Swid,
5967
)
@@ -455,6 +463,35 @@ def get_bom_with_component_setuptools_complete() -> Bom:
455463
return _make_bom(components=[get_component_setuptools_complete()])
456464

457465

466+
def get_bom_with_component_evidence() -> Bom:
467+
bom = _make_bom()
468+
tool_component = Component(
469+
name='product-cbom-generator',
470+
type=ComponentType.APPLICATION,
471+
bom_ref='cbom:generator'
472+
)
473+
bom.metadata.tools.components.add(tool_component)
474+
bom.metadata.component = Component(
475+
name='root-component',
476+
type=ComponentType.APPLICATION,
477+
licenses=[DisjunctiveLicense(id='MIT')],
478+
bom_ref='myApp',
479+
)
480+
component = Component(
481+
name='setuptools', version='50.3.2',
482+
bom_ref='pkg:pypi/[email protected]?extension=tar.gz',
483+
purl=PackageURL(
484+
type='pypi', name='setuptools', version='50.3.2', qualifiers='extension=tar.gz'
485+
),
486+
licenses=[DisjunctiveLicense(id='MIT')],
487+
author='Test Author'
488+
)
489+
component.evidence = get_component_evidence_basic(tools=[tool_component])
490+
bom.components.add(component)
491+
bom.register_dependency(bom.metadata.component, depends_on=[component])
492+
return bom
493+
494+
458495
def get_bom_with_component_setuptools_with_vulnerability() -> Bom:
459496
bom = _make_bom()
460497
component = get_component_setuptools_simple()
@@ -737,6 +774,54 @@ def get_component_setuptools_complete(include_pedigree: bool = True) -> Componen
737774
return component
738775

739776

777+
def get_component_evidence_basic(tools: Iterable[Tool]) -> ComponentEvidence:
778+
"""
779+
Returns a basic ComponentEvidence object for testing.
780+
"""
781+
return ComponentEvidence(
782+
identity=[
783+
Identity(
784+
field=IdentityFieldType.NAME,
785+
confidence=Decimal('0.9'),
786+
concluded_value='example-component',
787+
methods=[
788+
Method(
789+
technique=AnalysisTechnique.SOURCE_CODE_ANALYSIS,
790+
confidence=Decimal('0.8'), value='analysis-tool'
791+
)
792+
],
793+
tools=[tool.bom_ref for tool in tools]
794+
)
795+
],
796+
occurrences=[
797+
Occurrence(
798+
location='path/to/file',
799+
line=42,
800+
offset=16,
801+
symbol='exampleSymbol',
802+
additional_context='Found in source code',
803+
)
804+
],
805+
callstack=CallStack(
806+
frames=[
807+
StackFrame(
808+
package='example.package',
809+
module='example.module',
810+
function='example_function',
811+
parameters=['param1', 'param2'],
812+
line=10,
813+
column=5,
814+
full_filename='path/to/file',
815+
)
816+
]
817+
),
818+
licenses=[DisjunctiveLicense(id='MIT')],
819+
copyright=[
820+
Copyright(text='Commercial'), Copyright(text='Commercial 2')
821+
]
822+
)
823+
824+
740825
def get_component_setuptools_simple(
741826
bom_ref: Optional[str] = 'pkg:pypi/[email protected]?extension=tar.gz'
742827
) -> Component:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" ?>
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.0" version="1">
3+
<components>
4+
<component type="library">
5+
<name>setuptools</name>
6+
<version>50.3.2</version>
7+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
8+
<modified>false</modified>
9+
</component>
10+
</components>
11+
</bom>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" ?>
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.1" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
3+
<components>
4+
<component type="library" bom-ref="pkg:pypi/[email protected]?extension=tar.gz">
5+
<name>setuptools</name>
6+
<version>50.3.2</version>
7+
<licenses>
8+
<license>
9+
<id>MIT</id>
10+
</license>
11+
</licenses>
12+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
13+
</component>
14+
</components>
15+
</bom>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"components": [
3+
{
4+
"author": "Test Author",
5+
"bom-ref": "pkg:pypi/[email protected]?extension=tar.gz",
6+
"licenses": [
7+
{
8+
"license": {
9+
"id": "MIT"
10+
}
11+
}
12+
],
13+
"name": "setuptools",
14+
"purl": "pkg:pypi/[email protected]?extension=tar.gz",
15+
"type": "library",
16+
"version": "50.3.2"
17+
}
18+
],
19+
"dependencies": [
20+
{
21+
"dependsOn": [
22+
"pkg:pypi/[email protected]?extension=tar.gz"
23+
],
24+
"ref": "myApp"
25+
},
26+
{
27+
"ref": "pkg:pypi/[email protected]?extension=tar.gz"
28+
}
29+
],
30+
"metadata": {
31+
"component": {
32+
"bom-ref": "myApp",
33+
"licenses": [
34+
{
35+
"license": {
36+
"id": "MIT"
37+
}
38+
}
39+
],
40+
"name": "root-component",
41+
"type": "application",
42+
"version": ""
43+
},
44+
"timestamp": "2023-01-07T13:44:32.312678+00:00",
45+
"tools": [
46+
{
47+
"name": "product-cbom-generator"
48+
}
49+
]
50+
},
51+
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
52+
"version": 1,
53+
"$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json",
54+
"bomFormat": "CycloneDX",
55+
"specVersion": "1.2"
56+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" ?>
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.2" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
3+
<metadata>
4+
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
5+
<tools>
6+
<tool>
7+
<name>product-cbom-generator</name>
8+
</tool>
9+
</tools>
10+
<component type="application" bom-ref="myApp">
11+
<name>root-component</name>
12+
<version/>
13+
<licenses>
14+
<license>
15+
<id>MIT</id>
16+
</license>
17+
</licenses>
18+
</component>
19+
</metadata>
20+
<components>
21+
<component type="library" bom-ref="pkg:pypi/[email protected]?extension=tar.gz">
22+
<author>Test Author</author>
23+
<name>setuptools</name>
24+
<version>50.3.2</version>
25+
<licenses>
26+
<license>
27+
<id>MIT</id>
28+
</license>
29+
</licenses>
30+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
31+
</component>
32+
</components>
33+
<dependencies>
34+
<dependency ref="myApp">
35+
<dependency ref="pkg:pypi/[email protected]?extension=tar.gz"/>
36+
</dependency>
37+
<dependency ref="pkg:pypi/[email protected]?extension=tar.gz"/>
38+
</dependencies>
39+
</bom>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{
2+
"components": [
3+
{
4+
"author": "Test Author",
5+
"bom-ref": "pkg:pypi/[email protected]?extension=tar.gz",
6+
"evidence": {
7+
"copyright": [
8+
{
9+
"text": "Commercial"
10+
},
11+
{
12+
"text": "Commercial 2"
13+
}
14+
],
15+
"licenses": [
16+
{
17+
"license": {
18+
"id": "MIT"
19+
}
20+
}
21+
]
22+
},
23+
"licenses": [
24+
{
25+
"license": {
26+
"id": "MIT"
27+
}
28+
}
29+
],
30+
"name": "setuptools",
31+
"purl": "pkg:pypi/[email protected]?extension=tar.gz",
32+
"type": "library",
33+
"version": "50.3.2"
34+
}
35+
],
36+
"dependencies": [
37+
{
38+
"dependsOn": [
39+
"pkg:pypi/[email protected]?extension=tar.gz"
40+
],
41+
"ref": "myApp"
42+
},
43+
{
44+
"ref": "pkg:pypi/[email protected]?extension=tar.gz"
45+
}
46+
],
47+
"metadata": {
48+
"component": {
49+
"bom-ref": "myApp",
50+
"licenses": [
51+
{
52+
"license": {
53+
"id": "MIT"
54+
}
55+
}
56+
],
57+
"name": "root-component",
58+
"type": "application",
59+
"version": ""
60+
},
61+
"timestamp": "2023-01-07T13:44:32.312678+00:00",
62+
"tools": [
63+
{
64+
"name": "product-cbom-generator"
65+
}
66+
]
67+
},
68+
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
69+
"version": 1,
70+
"$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json",
71+
"bomFormat": "CycloneDX",
72+
"specVersion": "1.3"
73+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" ?>
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
3+
<metadata>
4+
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
5+
<tools>
6+
<tool>
7+
<name>product-cbom-generator</name>
8+
</tool>
9+
</tools>
10+
<component type="application" bom-ref="myApp">
11+
<name>root-component</name>
12+
<version/>
13+
<licenses>
14+
<license>
15+
<id>MIT</id>
16+
</license>
17+
</licenses>
18+
</component>
19+
</metadata>
20+
<components>
21+
<component type="library" bom-ref="pkg:pypi/[email protected]?extension=tar.gz">
22+
<author>Test Author</author>
23+
<name>setuptools</name>
24+
<version>50.3.2</version>
25+
<licenses>
26+
<license>
27+
<id>MIT</id>
28+
</license>
29+
</licenses>
30+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
31+
<evidence>
32+
<licenses>
33+
<license>
34+
<id>MIT</id>
35+
</license>
36+
</licenses>
37+
<copyright>
38+
<text>Commercial</text>
39+
<text>Commercial 2</text>
40+
</copyright>
41+
</evidence>
42+
</component>
43+
</components>
44+
<dependencies>
45+
<dependency ref="myApp">
46+
<dependency ref="pkg:pypi/[email protected]?extension=tar.gz"/>
47+
</dependency>
48+
<dependency ref="pkg:pypi/[email protected]?extension=tar.gz"/>
49+
</dependencies>
50+
</bom>

0 commit comments

Comments
 (0)