Skip to content

Commit d474193

Browse files
committed
Convert a SPDX cpe externalReference into the item level cpe field
Signed-off-by: andreas hilti <69210561+andreas-hilti@users.noreply.github.com>
1 parent 6bffc9a commit d474193

File tree

6 files changed

+30
-9
lines changed

6 files changed

+30
-9
lines changed

.markdownlint.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"MD013": {
3-
"code_blocks": false
3+
"code_blocks": false,
4+
"tables": false
45
}
56
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ minimising data loss during conversion, pull requests are welcome :)
3939
| License information in files | Needs review, the way SPDX and CycloneDX handle license information evidence is slightly different. |
4040
| Snippet Information | Snippets are not currently supported by CycloneDX |
4141
| Non-SPDX licenses | Implementation pending |
42+
| CPE for Component Identity | SPDX supports multiple CPEs for a package. But doesn't support specifying if any are a component identifier. The first one is used as component CPE.|
4243

4344
#### CycloneDX -> SPDX
4445

src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/ExternalRefs.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ public static void AddSpdxExternalRefs(this Component component, List<ExternalRe
142142
{
143143
refPropValue = $"{extRef.ReferenceLocator} {extRef.Comment}";
144144
}
145+
if ((refPropName == PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE22 ||
146+
refPropName == PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE23) && component.Cpe == null)
147+
{
148+
// For the first seen cpe, assume it is the component's cpe.
149+
component.Cpe = refPropValue;
150+
continue;
151+
}
145152
component.Properties.AddSpdxElement(refPropName, refPropValue);
146153
}
147154
}

src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/SpdxDocumentHelpers.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,24 @@ public static void AddCycloneDXComponents(this SpdxDocument doc, Bom bom)
200200
package.Checksums = component.GetSpdxChecksums();
201201
package.ExternalRefs = component.GetSpdxExternalRefs();
202202

203+
if (component.Cpe != null)
204+
{
205+
if (package.ExternalRefs == null)
206+
{
207+
package.ExternalRefs = new List<ExternalRef>();
208+
}
209+
210+
// Insert at the start, so that this correctly roundtrips, i.e. if there are
211+
// multiple CPEs, always pick the first as the component's cpe.
212+
var referenceType = component.Cpe.StartsWith("cpe:/", true, culture: System.Globalization.CultureInfo.InvariantCulture) ? "cpe22Type" : "cpe23Type";
213+
package.ExternalRefs.Insert(0, new ExternalRef
214+
{
215+
ReferenceCategory = ExternalRefCategory.SECURITY,
216+
ReferenceType = referenceType,
217+
ReferenceLocator = component.Cpe,
218+
});
219+
}
220+
203221
package.DownloadLocation = component.Properties?.GetSpdxElement(PropertyTaxonomy.DOWNLOAD_LOCATION) ?? "NOASSERTION";
204222
package.Homepage = component.Properties?.GetSpdxElement(PropertyTaxonomy.HOMEPAGE);
205223

tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromSpdxToCDXTest_v2.2document.snap

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
}
114114
],
115115
"copyright": "Copyright 2008-2010 John Smith",
116+
"cpe": "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*",
116117
"externalReferences": [
117118
{
118119
"url": "http://ftp.gnu.org/gnu/glibc/glibc-ports-2.15.tar.gz",
@@ -172,10 +173,6 @@
172173
"name": "spdx:package:originator:email",
173174
"value": "contact@example.com"
174175
},
175-
{
176-
"name": "spdx:external-reference:security:cpe23",
177-
"value": "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
178-
},
179176
{
180177
"name": "spdx:external-reference:other:http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#LocationRef-acmeforge",
181178
"value": "acmecorp/acmenator/4.1.3-alpha This is the external ref for Acme"

tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromSpdxToCDXTest_v2.3document.snap

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
}
110110
],
111111
"copyright": "Copyright 2008-2010 John Smith",
112+
"cpe": "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*",
112113
"externalReferences": [
113114
{
114115
"url": "http://ftp.gnu.org/gnu/glibc/glibc-ports-2.15.tar.gz",
@@ -184,10 +185,6 @@
184185
"name": "spdx:checksum:adler32",
185186
"value": "85ed0817af83a24ad8da68c2b5094de69833983c"
186187
},
187-
{
188-
"name": "spdx:external-reference:security:cpe23",
189-
"value": "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
190-
},
191188
{
192189
"name": "spdx:external-reference:persistent-id:swh",
193190
"value": "acmecorp/acmenator/4.1.3-alpha This is the external ref for Acme"

0 commit comments

Comments
 (0)