Skip to content

Commit

Permalink
Add package URL (purl) to SPDX SBOM files
Browse files Browse the repository at this point in the history
Add a package URL to generated SBOM files so that vulnerability
databases can start linking CVEs to vcpkg port versions.

Fixes microsoft/vcpkg#39254.
See also package-url/purl-spec#217 that has
not been resolved yet but should be resolved before this commit is
merged.
  • Loading branch information
aristotelos committed Aug 27, 2024
1 parent 4063a94 commit 08abaaf
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
6 changes: 6 additions & 0 deletions include/vcpkg/base/contractual-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ namespace vcpkg
inline constexpr StringLiteral SpdxDocumentNamespace = "documentNamespace";
inline constexpr StringLiteral SpdxDownloadLocation = "downloadLocation";
inline constexpr StringLiteral SpdxElementId = "spdxElementId";
inline constexpr StringLiteral SpdxExternalRefs = "externalRefs";
inline constexpr StringLiteral SpdxExternalReferenceCategory = "referenceCategory";
inline constexpr StringLiteral SpdxExternalReferenceCategoryPackageManager = "PACKAGE_MANAGER";
inline constexpr StringLiteral SpdxExternalReferenceLocator = "referenceLocator";
inline constexpr StringLiteral SpdxExternalReferenceType = "referenceType";
inline constexpr StringLiteral SpdxExternalReferenceTypePurl = "purl";
inline constexpr StringLiteral SpdxFileName = "fileName";
inline constexpr StringLiteral SpdxGeneratedFrom = "GENERATED_FROM";
inline constexpr StringLiteral SpdxGenerates = "GENERATES";
Expand Down
27 changes: 24 additions & 3 deletions src/vcpkg-test/spdx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,14 @@ TEST_CASE ("spdx maximum serialization", "[spdx]")
"copyrightText": "NOASSERTION",
"summary": "summary",
"description": "description",
"comment": "This is the port (recipe) consumed by vcpkg."
"comment": "This is the port (recipe) consumed by vcpkg.",
"externalRefs": [
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:vcpkg/zlib@1.0?registry_url=git%3A%2F%2Fsome-vcs-url&port_version=5",
"referenceType": "purl"
}
]
},
{
"name": "zlib:arm-uwp",
Expand Down Expand Up @@ -247,7 +254,14 @@ TEST_CASE ("spdx minimum serialization", "[spdx]")
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"comment": "This is the port (recipe) consumed by vcpkg."
"comment": "This is the port (recipe) consumed by vcpkg.",
"externalRefs": [
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:vcpkg/zlib@1.0",
"referenceType": "purl"
}
]
},
{
"name": "zlib:arm-uwp",
Expand Down Expand Up @@ -366,7 +380,14 @@ TEST_CASE ("spdx concat resources", "[spdx]")
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"comment": "This is the port (recipe) consumed by vcpkg."
"comment": "This is the port (recipe) consumed by vcpkg.",
"externalRefs": [
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:vcpkg/zlib@1.0",
"referenceType": "purl"
}
]
},
{
"name": "zlib:arm-uwp",
Expand Down
15 changes: 15 additions & 0 deletions src/vcpkg/spdx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,21 @@ std::string vcpkg::create_spdx_sbom(const InstallPlanAction& action,
rel.insert(SpdxRelationshipType, SpdxContains);
rel.insert(SpdxRelatedSpdxElement, fmt::format("SPDXRef-file-{}", i));
}
auto& external_refs = obj.insert(SpdxExternalRefs, Json::Array());
auto& external_ref = external_refs.push_back(Json::Object());
external_ref.insert(SpdxExternalReferenceCategory, SpdxExternalReferenceCategoryPackageManager);
external_ref.insert(SpdxExternalReferenceType, SpdxExternalReferenceTypePurl);
std::string purl_qualifiers = "";
if (!scfl.spdx_location.empty())
{
purl_qualifiers = Strings::concat("?registry_url=", Strings::percent_encode(scfl.spdx_location));
if (cpgh.version.port_version > 0)
{
purl_qualifiers += fmt::format("&port_version={}", cpgh.version.port_version);
}
}
external_ref.insert(SpdxExternalReferenceLocator,
Strings::concat("pkg:vcpkg/", action.spec.name(), '@', cpgh.version.text, purl_qualifiers));
}
{
auto& obj = packages.push_back(Json::Object());
Expand Down

0 comments on commit 08abaaf

Please sign in to comment.