Repository: conan-io/conan
Pull request #18358 (2025-05-26 10:07:16)

Fix | Validate if the licenses in the SBOM are SPDX compatible
Changelog: Fix: Validate if the licenses in the SBOM are SPDX compatible

The SBOM should use the "id" field in licenses when it is a SPDX license, or "name" if it is not.

Close: https://github.com/conan-io/conan/issues/18353



Patch:
diff --git a/conan/tools/sbom/cyclonedx.py b/conan/tools/sbom/cyclonedx.py
index cca6020c0..e15585601 100644
--- a/conan/tools/sbom/cyclonedx.py
+++ b/conan/tools/sbom/cyclonedx.py
@@ -52,15 +52,6 @@ def cyclonedx_1_4(conanfile, name=None, add_build=False, add_tests=False, **kwar
             deps["dependsOn"] = depends_on
         dependencies.append(deps)
 
-    def _calculate_licenses(component):
-        if isinstance(component.conanfile.license, str): # Just one license
-            return [{"license": {
-                        "id": component.conanfile.license
-                    }}]
-        return [{"license": {
-                    "id": l
-                }} for l in component.conanfile.license]
-
     sbom_cyclonedx_1_4 = {
         **({"components": [{
             "author": node.conanfile.author or "Unknown",
@@ -152,15 +143,6 @@ def cyclonedx_1_6(conanfile, name=None, add_build=False, add_tests=False, **kwar
             deps["dependsOn"] = depends_on
         dependencies.append(deps)
 
-    def _calculate_licenses(component):
-        if isinstance(component.conanfile.license, str): # Just one license
-            return [{"license": {
-                        "id": component.conanfile.license
-                    }}]
-        return [{"license": {
-                    "id": l
-                }} for l in component.conanfile.license]
-
     sbom_cyclonedx_1_6 = {
         **({"components": [{
             **({"authors": [{"name": node.conanfile.author}]} if node.conanfile.author else {}),
@@ -199,3 +181,21 @@ def cyclonedx_1_6(conanfile, name=None, add_build=False, add_tests=False, **kwar
         "version": 1,
     }
     return sbom_cyclonedx_1_6
+
+
+def _calculate_licenses(component):
+    from conan.tools.sbom.spdx_licenses import NORMALIZED_VALID_SPDX_LICENSES
+    licenses = component.conanfile.license
+
+    if isinstance(licenses, str): # Just one license
+        field = "id" if licenses.lower() in NORMALIZED_VALID_SPDX_LICENSES else "name"
+        return [{"license":{ field: licenses }}]
+
+    return [ # More than one license
+        {"license": {
+            "id" if l.lower() in NORMALIZED_VALID_SPDX_LICENSES else "name": l
+        }}
+        for l in licenses
+    ]
+
+
diff --git a/conan/tools/sbom/spdx_licenses.py b/conan/tools/sbom/spdx_licenses.py
new file mode 100644
index 000000000..b64d9d906
--- /dev/null
+++ b/conan/tools/sbom/spdx_licenses.py
@@ -0,0 +1,1368 @@
+# This list comes from: https://github.com/spdx/license-list-data/blob/v3.26.0/json/licenses.json
+VALID_SPDX_LICENSES = {
+    "0BSD",
+    "3D-Slicer-1.0",
+    "AAL",
+    "Abstyles",
+    "AdaCore-doc",
+    "Adobe-2006",
+    "Adobe-Display-PostScript",
+    "Adobe-Glyph",
+    "Adobe-Utopia",
+    "ADSL",
+    "AFL-1.1",
+    "AFL-1.2",
+    "AFL-2.0",
+    "AFL-2.1",
+    "AFL-3.0",
+    "Afmparse",
+    "AGPL-1.0",
+    "AGPL-1.0-only",
+    "AGPL-1.0-or-later",
+    "AGPL-3.0",
+    "AGPL-3.0-only",
+    "AGPL-3.0-or-later",
+    "Aladdin",
+    "AMD-newlib",
+    "AMDPLPA",
+    "AML",
+    "AML-glslang",
+    "AMPAS",
+    "ANTLR-PD",
+    "ANTLR-PD-fallback",
+    "any-OSI",
+    "any-OSI-perl-modules",
+    "Apache-1.0",
+    "Apache-1.1",
+    "Apache-2.0",
+    "APAFML",
+    "APL-1.0",
+    "App-s2p",
+    "APSL-1.0",
+    "APSL-1.1",
+    "APSL-1.2",
+    "APSL-2.0",
+    "Arphic-1999",
+    "Artistic-1.0",
+    "Artistic-1.0-cl8",
+    "Artistic-1.0-Perl",
+    "Artistic-2.0",
+    "ASWF-Digital-Assets-1.0",
+    "ASWF-Digital-Assets-1.1",
+    "Baekmuk",
+    "Bahyph",
+    "Barr",
+    "bcrypt-Solar-Designer",
+    "Beerware",
+    "Bitstream-Charter",
+    "Bitstream-Vera",
+    "BitTorrent-1.0",
+    "BitTorrent-1.1",
+    "blessing",
+    "BlueOak-1.0.0",
+    "Boehm-GC",
+    "Boehm-GC-without-fee",
+    "Borceux",
+    "Brian-Gladman-2-Clause",
+    "Brian-Gladman-3-Clause",
+    "BSD-1-Clause",
+    "BSD-2-Clause",
+    "BSD-2-Clause-Darwin",
+    "BSD-2-Clause-first-lines",
+    "BSD-2-Clause-FreeBSD",
+    "BSD-2-Clause-NetBSD",
+    "BSD-2-Clause-Patent",
+    "BSD-2-Clause-Views",
+    "BSD-3-Clause",
+    "BSD-3-Clause-acpica",
+    "BSD-3-Clause-Attribution",
+    "BSD-3-Clause-Clear",
+    "BSD-3-Clause-flex",
+    "BSD-3-Clause-HP",
+    "BSD-3-Clause-LBNL",
+    "BSD-3-Clause-Modification",
+    "BSD-3-Clause-No-Military-License",
+    "BSD-3-Clause-No-Nuclear-License",
+    "BSD-3-Clause-No-Nuclear-License-2014",
+    "BSD-3-Clause-No-Nuclear-Warranty",
+    "BSD-3-Clause-Open-MPI",
+    "BSD-3-Clause-Sun",
+    "BSD-4-Clause",
+    "BSD-4-Clause-Shortened",
+    "BSD-4-Clause-UC",
+    "BSD-4.3RENO",
+    "BSD-4.3TAHOE",
+    "BSD-Advertising-Acknowledgement",
+    "BSD-Attribution-HPND-disclaimer",
+    "BSD-Inferno-Nettverk",
+    "BSD-Protection",
+    "BSD-Source-beginning-file",
+    "BSD-Source-Code",
+    "BSD-Systemics",
+    "BSD-Systemics-W3Works",
+    "BSL-1.0",
+    "BUSL-1.1",
+    "bzip2-1.0.5",
+    "bzip2-1.0.6",
+    "C-UDA-1.0",
+    "CAL-1.0",
+    "CAL-1.0-Combined-Work-Exception",
+    "Caldera",
+    "Caldera-no-preamble",
+    "Catharon",
+    "CATOSL-1.1",
+    "CC-BY-1.0",
+    "CC-BY-2.0",
+    "CC-BY-2.5",
+    "CC-BY-2.5-AU",
+    "CC-BY-3.0",
+    "CC-BY-3.0-AT",
+    "CC-BY-3.0-AU",
+    "CC-BY-3.0-DE",
+    "CC-BY-3.0-IGO",
+    "CC-BY-3.0-NL",
+    "CC-BY-3.0-US",
+    "CC-BY-4.0",
+    "CC-BY-NC-1.0",
+    "CC-BY-NC-2.0",
+    "CC-BY-NC-2.5",
+    "CC-BY-NC-3.0",
+    "CC-BY-NC-3.0-DE",
+    "CC-BY-NC-4.0",
+    "CC-BY-NC-ND-1.0",
+    "CC-BY-NC-ND-2.0",
+    "CC-BY-NC-ND-2.5",
+    "CC-BY-NC-ND-3.0",
+    "CC-BY-NC-ND-3.0-DE",
+    "CC-BY-NC-ND-3.0-IGO",
+    "CC-BY-NC-ND-4.0",
+    "CC-BY-NC-SA-1.0",
+    "CC-BY-NC-SA-2.0",
+    "CC-BY-NC-SA-2.0-DE",
+    "CC-BY-NC-SA-2.0-FR",
+    "CC-BY-NC-SA-2.0-UK",
+    "CC-BY-NC-SA-2.5",
+    "CC-BY-NC-SA-3.0",
+    "CC-BY-NC-SA-3.0-DE",
+    "CC-BY-NC-SA-3.0-IGO",
+    "CC-BY-NC-SA-4.0",
+    "CC-BY-ND-1.0",
+    "CC-BY-ND-2.0",
+    "CC-BY-ND-2.5",
+    "CC-BY-ND-3.0",
+    "CC-BY-ND-3.0-DE",
+    "CC-BY-ND-4.0",
+    "CC-BY-SA-1.0",
+    "CC-BY-SA-2.0",
+    "CC-BY-SA-2.0-UK",
+    "CC-BY-SA-2.1-JP",
+    "CC-BY-SA-2.5",
+    "CC-BY-SA-3.0",
+    "CC-BY-SA-3.0-AT",
+    "CC-BY-SA-3.0-DE",
+    "CC-BY-SA-3.0-IGO",
+    "CC-BY-SA-4.0",
+    "CC-PDDC",
+    "CC-PDM-1.0",
+    "CC-SA-1.0",
+    "CC0-1.0",
+    "CDDL-1.0",
+    "CDDL-1.1",
+    "CDL-1.0",
+    "CDLA-Permissive-1.0",
+    "CDLA-Permissive-2.0",
+    "CDLA-Sharing-1.0",
+    "CECILL-1.0",
+    "CECILL-1.1",
+    "CECILL-2.0",
+    "CECILL-2.1",
+    "CECILL-B",
+    "CECILL-C",
+    "CERN-OHL-1.1",
+    "CERN-OHL-1.2",
+    "CERN-OHL-P-2.0",
+    "CERN-OHL-S-2.0",
+    "CERN-OHL-W-2.0",
+    "CFITSIO",
+    "check-cvs",
+    "checkmk",
+    "ClArtistic",
+    "Clips",
+    "CMU-Mach",
+    "CMU-Mach-nodoc",
+    "CNRI-Jython",
+    "CNRI-Python",
+    "CNRI-Python-GPL-Compatible",
+    "COIL-1.0",
+    "Community-Spec-1.0",
+    "Condor-1.1",
+    "copyleft-next-0.3.0",
+    "copyleft-next-0.3.1",
+    "Cornell-Lossless-JPEG",
+    "CPAL-1.0",
+    "CPL-1.0",
+    "CPOL-1.02",
+    "Cronyx",
+    "Crossword",
+    "CrystalStacker",
+    "CUA-OPL-1.0",
+    "Cube",
+    "curl",
+    "cve-tou",
+    "D-FSL-1.0",
+    "DEC-3-Clause",
+    "diffmark",
+    "DL-DE-BY-2.0",
+    "DL-DE-ZERO-2.0",
+    "DOC",
+    "DocBook-Schema",
+    "DocBook-Stylesheet",
+    "DocBook-XML",
+    "Dotseqn",
+    "DRL-1.0",
+    "DRL-1.1",
+    "DSDP",
+    "dtoa",
+    "dvipdfm",
+    "ECL-1.0",
+    "ECL-2.0",
+    "eCos-2.0",
+    "EFL-1.0",
+    "EFL-2.0",
+    "eGenix",
+    "Elastic-2.0",
+    "Entessa",
+    "EPICS",
+    "EPL-1.0",
+    "EPL-2.0",
+    "ErlPL-1.1",
+    "etalab-2.0",
+    "EUDatagrid",
+    "EUPL-1.0",
+    "EUPL-1.1",
+    "EUPL-1.2",
+    "Eurosym",
+    "Fair",
+    "FBM",
+    "FDK-AAC",
+    "Ferguson-Twofish",
+    "Frameworx-1.0",
+    "FreeBSD-DOC",
+    "FreeImage",
+    "FSFAP",
+    "FSFAP-no-warranty-disclaimer",
+    "FSFUL",
+    "FSFULLR",
+    "FSFULLRWD",
+    "FTL",
+    "Furuseth",
+    "fwlw",
+    "GCR-docs",
+    "GD",
+    "generic-xts",
+    "GFDL-1.1",
+    "GFDL-1.1-invariants-only",
+    "GFDL-1.1-invariants-or-later",
+    "GFDL-1.1-no-invariants-only",
+    "GFDL-1.1-no-invariants-or-later",
+    "GFDL-1.1-only",
+    "GFDL-1.1-or-later",
+    "GFDL-1.2",
+    "GFDL-1.2-invariants-only",
+    "GFDL-1.2-invariants-or-later",
+    "GFDL-1.2-no-invariants-only",
+    "GFDL-1.2-no-invariants-or-later",
+    "GFDL-1.2-only",
+    "GFDL-1.2-or-later",
+    "GFDL-1.3",
+    "GFDL-1.3-invariants-only",
+    "GFDL-1.3-invariants-or-later",
+    "GFDL-1.3-no-invariants-only",
+    "GFDL-1.3-no-invariants-or-later",
+    "GFDL-1.3-only",
+    "GFDL-1.3-or-later",
+    "Giftware",
+    "GL2PS",
+    "Glide",
+    "Glulxe",
+    "GLWTPL",
+    "gnuplot",
+    "GPL-1.0",
+    "GPL-1.0+",
+    "GPL-1.0-only",
+    "GPL-1.0-or-later",
+    "GPL-2.0",
+    "GPL-2.0+",
+    "GPL-2.0-only",
+    "GPL-2.0-or-later",
+    "GPL-2.0-with-autoconf-exception",
+    "GPL-2.0-with-bison-exception",
+    "GPL-2.0-with-classpath-exception",
+    "GPL-2.0-with-font-exception",
+    "GPL-2.0-with-GCC-exception",
+    "GPL-3.0",
+    "GPL-3.0+",
+    "GPL-3.0-only",
+    "GPL-3.0-or-later",
+    "GPL-3.0-with-autoconf-exception",
+    "GPL-3.0-with-GCC-exception",
+    "Graphics-Gems",
+    "gSOAP-1.3b",
+    "gtkbook",
+    "Gutmann",
+    "HaskellReport",
+    "hdparm",
+    "HIDAPI",
+    "Hippocratic-2.1",
+    "HP-1986",
+    "HP-1989",
+    "HPND",
+    "HPND-DEC",
+    "HPND-doc",
+    "HPND-doc-sell",
+    "HPND-export-US",
+    "HPND-export-US-acknowledgement",
+    "HPND-export-US-modify",
+    "HPND-export2-US",
+    "HPND-Fenneberg-Livingston",
+    "HPND-INRIA-IMAG",
+    "HPND-Intel",
+    "HPND-Kevlin-Henney",
+    "HPND-Markus-Kuhn",
+    "HPND-merchantability-variant",
+    "HPND-MIT-disclaimer",
+    "HPND-Netrek",
+    "HPND-Pbmplus",
+    "HPND-sell-MIT-disclaimer-xserver",
+    "HPND-sell-regexpr",
+    "HPND-sell-variant",
+    "HPND-sell-variant-MIT-disclaimer",
+    "HPND-sell-variant-MIT-disclaimer-rev",
+    "HPND-UC",
+    "HPND-UC-export-US",
+    "HTMLTIDY",
+    "IBM-pibs",
+    "ICU",
+    "IEC-Code-Components-EULA",
+    "IJG",
+    "IJG-short",
+    "ImageMagick",
+    "iMatix",
+    "Imlib2",
+    "Info-ZIP",
+    "Inner-Net-2.0",
+    "InnoSetup",
+    "Intel",
+    "Intel-ACPI",
+    "Interbase-1.0",
+    "IPA",
+    "IPL-1.0",
+    "ISC",
+    "ISC-Veillard",
+    "Jam",
+    "JasPer-2.0",
+    "JPL-image",
+    "JPNIC",
+    "JSON",
+    "Kastrup",
+    "Kazlib",
+    "Knuth-CTAN",
+    "LAL-1.2",
+    "LAL-1.3",
+    "Latex2e",
+    "Latex2e-translated-notice",
+    "Leptonica",
+    "LGPL-2.0",
+    "LGPL-2.0+",
+    "LGPL-2.0-only",
+    "LGPL-2.0-or-later",
+    "LGPL-2.1",
+    "LGPL-2.1+",
+    "LGPL-2.1-only",
+    "LGPL-2.1-or-later",
+    "LGPL-3.0",
+    "LGPL-3.0+",
+    "LGPL-3.0-only",
+    "LGPL-3.0-or-later",
+    "LGPLLR",
+    "Libpng",
+    "libpng-2.0",
+    "libselinux-1.0",
+    "libtiff",
+    "libutil-David-Nugent",
+    "LiLiQ-P-1.1",
+    "LiLiQ-R-1.1",
+    "LiLiQ-Rplus-1.1",
+    "Linux-man-pages-1-para",
+    "Linux-man-pages-copyleft",
+    "Linux-man-pages-copyleft-2-para",
+    "Linux-man-pages-copyleft-var",
+    "Linux-OpenIB",
+    "LOOP",
+    "LPD-document",
+    "LPL-1.0",
+    "LPL-1.02",
+    "LPPL-1.0",
+    "LPPL-1.1",
+    "LPPL-1.2",
+    "LPPL-1.3a",
+    "LPPL-1.3c",
+    "lsof",
+    "Lucida-Bitmap-Fonts",
+    "LZMA-SDK-9.11-to-9.20",
+    "LZMA-SDK-9.22",
+    "Mackerras-3-Clause",
+    "Mackerras-3-Clause-acknowledgment",
+    "magaz",
+    "mailprio",
+    "MakeIndex",
+    "Martin-Birgmeier",
+    "McPhee-slideshow",
+    "metamail",
+    "Minpack",
+    "MIPS",
+    "MirOS",
+    "MIT",
+    "MIT-0",
+    "MIT-advertising",
+    "MIT-Click",
+    "MIT-CMU",
+    "MIT-enna",
+    "MIT-feh",
+    "MIT-Festival",
+    "MIT-Khronos-old",
+    "MIT-Modern-Variant",
+    "MIT-open-group",
+    "MIT-testregex",
+    "MIT-Wu",
+    "MITNFA",
+    "MMIXware",
+    "Motosoto",
+    "MPEG-SSG",
+    "mpi-permissive",
+    "mpich2",
+    "MPL-1.0",
+    "MPL-1.1",
+    "MPL-2.0",
+    "MPL-2.0-no-copyleft-exception",
+    "mplus",
+    "MS-LPL",
+    "MS-PL",
+    "MS-RL",
+    "MTLL",
+    "MulanPSL-1.0",
+    "MulanPSL-2.0",
+    "Multics",
+    "Mup",
+    "NAIST-2003",
+    "NASA-1.3",
+    "Naumen",
+    "NBPL-1.0",
+    "NCBI-PD",
+    "NCGL-UK-2.0",
+    "NCL",
+    "NCSA",
+    "Net-SNMP",
+    "NetCDF",
+    "Newsletr",
+    "NGPL",
+    "NICTA-1.0",
+    "NIST-PD",
+    "NIST-PD-fallback",
+    "NIST-Software",
+    "NLOD-1.0",
+    "NLOD-2.0",
+    "NLPL",
+    "Nokia",
+    "NOSL",
+    "Noweb",
+    "NPL-1.0",
+    "NPL-1.1",
+    "NPOSL-3.0",
+    "NRL",
+    "NTP",
+    "NTP-0",
+    "Nunit",
+    "O-UDA-1.0",
+    "OAR",
+    "OCCT-PL",
+    "OCLC-2.0",
+    "ODbL-1.0",
+    "ODC-By-1.0",
+    "OFFIS",
+    "OFL-1.0",
+    "OFL-1.0-no-RFN",
+    "OFL-1.0-RFN",
+    "OFL-1.1",
+    "OFL-1.1-no-RFN",
+    "OFL-1.1-RFN",
+    "OGC-1.0",
+    "OGDL-Taiwan-1.0",
+    "OGL-Canada-2.0",
+    "OGL-UK-1.0",
+    "OGL-UK-2.0",
+    "OGL-UK-3.0",
+    "OGTSL",
+    "OLDAP-1.1",
+    "OLDAP-1.2",
+    "OLDAP-1.3",
+    "OLDAP-1.4",
+    "OLDAP-2.0",
+    "OLDAP-2.0.1",
+    "OLDAP-2.1",
+    "OLDAP-2.2",
+    "OLDAP-2.2.1",
+    "OLDAP-2.2.2",
+    "OLDAP-2.3",
+    "OLDAP-2.4",
+    "OLDAP-2.5",
+    "OLDAP-2.6",
+    "OLDAP-2.7",
+    "OLDAP-2.8",
+    "OLFL-1.3",
+    "OML",
+    "OpenPBS-2.3",
+    "OpenSSL",
+    "OpenSSL-standalone",
+    "OpenVision",
+    "OPL-1.0",
+    "OPL-UK-3.0",
+    "OPUBL-1.0",
+    "OSET-PL-2.1",
+    "OSL-1.0",
+    "OSL-1.1",
+    "OSL-2.0",
+    "OSL-2.1",
+    "OSL-3.0",
+    "PADL",
+    "Parity-6.0.0",
+    "Parity-7.0.0",
+    "PDDL-1.0",
+    "PHP-3.0",
+    "PHP-3.01",
+    "Pixar",
+    "pkgconf",
+    "Plexus",
+    "pnmstitch",
+    "PolyForm-Noncommercial-1.0.0",
+    "PolyForm-Small-Business-1.0.0",
+    "PostgreSQL",
+    "PPL",
+    "PSF-2.0",
+    "psfrag",
+    "psutils",
+    "Python-2.0",
+    "Python-2.0.1",
+    "python-ldap",
+    "Qhull",
+    "QPL-1.0",
+    "QPL-1.0-INRIA-2004",
+    "radvd",
+    "Rdisc",
+    "RHeCos-1.1",
+    "RPL-1.1",
+    "RPL-1.5",
+    "RPSL-1.0",
+    "RSA-MD",
+    "RSCPL",
+    "Ruby",
+    "Ruby-pty",
+    "SAX-PD",
+    "SAX-PD-2.0",
+    "Saxpath",
+    "SCEA",
+    "SchemeReport",
+    "Sendmail",
+    "Sendmail-8.23",
+    "Sendmail-Open-Source-1.1",
+    "SGI-B-1.0",
+    "SGI-B-1.1",
+    "SGI-B-2.0",
+    "SGI-OpenGL",
+    "SGP4",
+    "SHL-0.5",
+    "SHL-0.51",
+    "SimPL-2.0",
+    "SISSL",
+    "SISSL-1.2",
+    "SL",
+    "Sleepycat",
+    "SMAIL-GPL",
+    "SMLNJ",
+    "SMPPL",
+    "SNIA",
+    "snprintf",
+    "softSurfer",
+    "Soundex",
+    "Spencer-86",
+    "Spencer-94",
+    "Spencer-99",
+    "SPL-1.0",
+    "ssh-keyscan",
+    "SSH-OpenSSH",
+    "SSH-short",
+    "SSLeay-standalone",
+    "SSPL-1.0",
+    "StandardML-NJ",
+    "SugarCRM-1.1.3",
+    "Sun-PPP",
+    "Sun-PPP-2000",
+    "SunPro",
+    "SWL",
+    "swrule",
+    "Symlinks",
+    "TAPR-OHL-1.0",
+    "TCL",
+    "TCP-wrappers",
+    "TermReadKey",
+    "TGPPL-1.0",
+    "ThirdEye",
+    "threeparttable",
+    "TMate",
+    "TORQUE-1.1",
+    "TOSL",
+    "TPDL",
+    "TPL-1.0",
+    "TrustedQSL",
+    "TTWL",
+    "TTYP0",
+    "TU-Berlin-1.0",
+    "TU-Berlin-2.0",
+    "Ubuntu-font-1.0",
+    "UCAR",
+    "UCL-1.0",
+    "ulem",
+    "UMich-Merit",
+    "Unicode-3.0",
+    "Unicode-DFS-2015",
+    "Unicode-DFS-2016",
+    "Unicode-TOU",
+    "UnixCrypt",
+    "Unlicense",
+    "UPL-1.0",
+    "URT-RLE",
+    "Vim",
+    "VOSTROM",
+    "VSL-1.0",
+    "W3C",
+    "W3C-19980720",
+    "W3C-20150513",
+    "w3m",
+    "Watcom-1.0",
+    "Widget-Workshop",
+    "Wsuipa",
+    "WTFPL",
+    "wwl",
+    "wxWindows",
+    "X11",
+    "X11-distribute-modifications-variant",
+    "X11-swapped",
+    "Xdebug-1.03",
+    "Xerox",
+    "Xfig",
+    "XFree86-1.1",
+    "xinetd",
+    "xkeyboard-config-Zinoviev",
+    "xlock",
+    "Xnet",
+    "xpp",
+    "XSkat",
+    "xzoom",
+    "YPL-1.0",
+    "YPL-1.1",
+    "Zed",
+    "Zeeff",
+    "Zend-2.0",
+    "Zimbra-1.3",
+    "Zimbra-1.4",
+    "Zlib",
+    "zlib-acknowledgement",
+    "ZPL-1.1",
+    "ZPL-2.0",
+    "ZPL-2.1"
+}
+
+
+
+NORMALIZED_VALID_SPDX_LICENSES = {
+    "0bsd",
+    "3d-slicer-1.0",
+    "aal",
+    "abstyles",
+    "adacore-doc",
+    "adobe-2006",
+    "adobe-display-postscript",
+    "adobe-glyph",
+    "adobe-utopia",
+    "adsl",
+    "afl-1.1",
+    "afl-1.2",
+    "afl-2.0",
+    "afl-2.1",
+    "afl-3.0",
+    "afmparse",
+    "agpl-1.0",
+    "agpl-1.0-only",
+    "agpl-1.0-or-later",
+    "agpl-3.0",
+    "agpl-3.0-only",
+    "agpl-3.0-or-later",
+    "aladdin",
+    "amd-newlib",
+    "amdplpa",
+    "aml",
+    "aml-glslang",
+    "ampas",
+    "antlr-pd",
+    "antlr-pd-fallback",
+    "any-osi",
+    "any-osi-perl-modules",
+    "apache-1.0",
+    "apache-1.1",
+    "apache-2.0",
+    "apafml",
+    "apl-1.0",
+    "app-s2p",
+    "apsl-1.0",
+    "apsl-1.1",
+    "apsl-1.2",
+    "apsl-2.0",
+    "arphic-1999",
+    "artistic-1.0",
+    "artistic-1.0-cl8",
+    "artistic-1.0-perl",
+    "artistic-2.0",
+    "aswf-digital-assets-1.0",
+    "aswf-digital-assets-1.1",
+    "baekmuk",
+    "bahyph",
+    "barr",
+    "bcrypt-solar-designer",
+    "beerware",
+    "bitstream-charter",
+    "bitstream-vera",
+    "bittorrent-1.0",
+    "bittorrent-1.1",
+    "blessing",
+    "blueoak-1.0.0",
+    "boehm-gc",
+    "boehm-gc-without-fee",
+    "borceux",
+    "brian-gladman-2-clause",
+    "brian-gladman-3-clause",
+    "bsd-1-clause",
+    "bsd-2-clause",
+    "bsd-2-clause-darwin",
+    "bsd-2-clause-first-lines",
+    "bsd-2-clause-freebsd",
+    "bsd-2-clause-netbsd",
+    "bsd-2-clause-patent",
+    "bsd-2-clause-views",
+    "bsd-3-clause",
+    "bsd-3-clause-acpica",
+    "bsd-3-clause-attribution",
+    "bsd-3-clause-clear",
+    "bsd-3-clause-flex",
+    "bsd-3-clause-hp",
+    "bsd-3-clause-lbnl",
+    "bsd-3-clause-modification",
+    "bsd-3-clause-no-military-license",
+    "bsd-3-clause-no-nuclear-license",
+    "bsd-3-clause-no-nuclear-license-2014",
+    "bsd-3-clause-no-nuclear-warranty",
+    "bsd-3-clause-open-mpi",
+    "bsd-3-clause-sun",
+    "bsd-4-clause",
+    "bsd-4-clause-shortened",
+    "bsd-4-clause-uc",
+    "bsd-4.3reno",
+    "bsd-4.3tahoe",
+    "bsd-advertising-acknowledgement",
+    "bsd-attribution-hpnd-disclaimer",
+    "bsd-inferno-nettverk",
+    "bsd-protection",
+    "bsd-source-beginning-file",
+    "bsd-source-code",
+    "bsd-systemics",
+    "bsd-systemics-w3works",
+    "bsl-1.0",
+    "busl-1.1",
+    "bzip2-1.0.5",
+    "bzip2-1.0.6",
+    "c-uda-1.0",
+    "cal-1.0",
+    "cal-1.0-combined-work-exception",
+    "caldera",
+    "caldera-no-preamble",
+    "catharon",
+    "catosl-1.1",
+    "cc-by-1.0",
+    "cc-by-2.0",
+    "cc-by-2.5",
+    "cc-by-2.5-au",
+    "cc-by-3.0",
+    "cc-by-3.0-at",
+    "cc-by-3.0-au",
+    "cc-by-3.0-de",
+    "cc-by-3.0-igo",
+    "cc-by-3.0-nl",
+    "cc-by-3.0-us",
+    "cc-by-4.0",
+    "cc-by-nc-1.0",
+    "cc-by-nc-2.0",
+    "cc-by-nc-2.5",
+    "cc-by-nc-3.0",
+    "cc-by-nc-3.0-de",
+    "cc-by-nc-4.0",
+    "cc-by-nc-nd-1.0",
+    "cc-by-nc-nd-2.0",
+    "cc-by-nc-nd-2.5",
+    "cc-by-nc-nd-3.0",
+    "cc-by-nc-nd-3.0-de",
+    "cc-by-nc-nd-3.0-igo",
+    "cc-by-nc-nd-4.0",
+    "cc-by-nc-sa-1.0",
+    "cc-by-nc-sa-2.0",
+    "cc-by-nc-sa-2.0-de",
+    "cc-by-nc-sa-2.0-fr",
+    "cc-by-nc-sa-2.0-uk",
+    "cc-by-nc-sa-2.5",
+    "cc-by-nc-sa-3.0",
+    "cc-by-nc-sa-3.0-de",
+    "cc-by-nc-sa-3.0-igo",
+    "cc-by-nc-sa-4.0",
+    "cc-by-nd-1.0",
+    "cc-by-nd-2.0",
+    "cc-by-nd-2.5",
+    "cc-by-nd-3.0",
+    "cc-by-nd-3.0-de",
+    "cc-by-nd-4.0",
+    "cc-by-sa-1.0",
+    "cc-by-sa-2.0",
+    "cc-by-sa-2.0-uk",
+    "cc-by-sa-2.1-jp",
+    "cc-by-sa-2.5",
+    "cc-by-sa-3.0",
+    "cc-by-sa-3.0-at",
+    "cc-by-sa-3.0-de",
+    "cc-by-sa-3.0-igo",
+    "cc-by-sa-4.0",
+    "cc-pddc",
+    "cc-pdm-1.0",
+    "cc-sa-1.0",
+    "cc0-1.0",
+    "cddl-1.0",
+    "cddl-1.1",
+    "cdl-1.0",
+    "cdla-permissive-1.0",
+    "cdla-permissive-2.0",
+    "cdla-sharing-1.0",
+    "cecill-1.0",
+    "cecill-1.1",
+    "cecill-2.0",
+    "cecill-2.1",
+    "cecill-b",
+    "cecill-c",
+    "cern-ohl-1.1",
+    "cern-ohl-1.2",
+    "cern-ohl-p-2.0",
+    "cern-ohl-s-2.0",
+    "cern-ohl-w-2.0",
+    "cfitsio",
+    "check-cvs",
+    "checkmk",
+    "clartistic",
+    "clips",
+    "cmu-mach",
+    "cmu-mach-nodoc",
+    "cnri-jython",
+    "cnri-python",
+    "cnri-python-gpl-compatible",
+    "coil-1.0",
+    "community-spec-1.0",
+    "condor-1.1",
+    "copyleft-next-0.3.0",
+    "copyleft-next-0.3.1",
+    "cornell-lossless-jpeg",
+    "cpal-1.0",
+    "cpl-1.0",
+    "cpol-1.02",
+    "cronyx",
+    "crossword",
+    "crystalstacker",
+    "cua-opl-1.0",
+    "cube",
+    "curl",
+    "cve-tou",
+    "d-fsl-1.0",
+    "dec-3-clause",
+    "diffmark",
+    "dl-de-by-2.0",
+    "dl-de-zero-2.0",
+    "doc",
+    "docbook-schema",
+    "docbook-stylesheet",
+    "docbook-xml",
+    "dotseqn",
+    "drl-1.0",
+    "drl-1.1",
+    "dsdp",
+    "dtoa",
+    "dvipdfm",
+    "ecl-1.0",
+    "ecl-2.0",
+    "ecos-2.0",
+    "efl-1.0",
+    "efl-2.0",
+    "egenix",
+    "elastic-2.0",
+    "entessa",
+    "epics",
+    "epl-1.0",
+    "epl-2.0",
+    "erlpl-1.1",
+    "etalab-2.0",
+    "eudatagrid",
+    "eupl-1.0",
+    "eupl-1.1",
+    "eupl-1.2",
+    "eurosym",
+    "fair",
+    "fbm",
+    "fdk-aac",
+    "ferguson-twofish",
+    "frameworx-1.0",
+    "freebsd-doc",
+    "freeimage",
+    "fsfap",
+    "fsfap-no-warranty-disclaimer",
+    "fsful",
+    "fsfullr",
+    "fsfullrwd",
+    "ftl",
+    "furuseth",
+    "fwlw",
+    "gcr-docs",
+    "gd",
+    "generic-xts",
+    "gfdl-1.1",
+    "gfdl-1.1-invariants-only",
+    "gfdl-1.1-invariants-or-later",
+    "gfdl-1.1-no-invariants-only",
+    "gfdl-1.1-no-invariants-or-later",
+    "gfdl-1.1-only",
+    "gfdl-1.1-or-later",
+    "gfdl-1.2",
+    "gfdl-1.2-invariants-only",
+    "gfdl-1.2-invariants-or-later",
+    "gfdl-1.2-no-invariants-only",
+    "gfdl-1.2-no-invariants-or-later",
+    "gfdl-1.2-only",
+    "gfdl-1.2-or-later",
+    "gfdl-1.3",
+    "gfdl-1.3-invariants-only",
+    "gfdl-1.3-invariants-or-later",
+    "gfdl-1.3-no-invariants-only",
+    "gfdl-1.3-no-invariants-or-later",
+    "gfdl-1.3-only",
+    "gfdl-1.3-or-later",
+    "giftware",
+    "gl2ps",
+    "glide",
+    "glulxe",
+    "glwtpl",
+    "gnuplot",
+    "gpl-1.0",
+    "gpl-1.0+",
+    "gpl-1.0-only",
+    "gpl-1.0-or-later",
+    "gpl-2.0",
+    "gpl-2.0+",
+    "gpl-2.0-only",
+    "gpl-2.0-or-later",
+    "gpl-2.0-with-autoconf-exception",
+    "gpl-2.0-with-bison-exception",
+    "gpl-2.0-with-classpath-exception",
+    "gpl-2.0-with-font-exception",
+    "gpl-2.0-with-gcc-exception",
+    "gpl-3.0",
+    "gpl-3.0+",
+    "gpl-3.0-only",
+    "gpl-3.0-or-later",
+    "gpl-3.0-with-autoconf-exception",
+    "gpl-3.0-with-gcc-exception",
+    "graphics-gems",
+    "gsoap-1.3b",
+    "gtkbook",
+    "gutmann",
+    "haskellreport",
+    "hdparm",
+    "hidapi",
+    "hippocratic-2.1",
+    "hp-1986",
+    "hp-1989",
+    "hpnd",
+    "hpnd-dec",
+    "hpnd-doc",
+    "hpnd-doc-sell",
+    "hpnd-export-us",
+    "hpnd-export-us-acknowledgement",
+    "hpnd-export-us-modify",
+    "hpnd-export2-us",
+    "hpnd-fenneberg-livingston",
+    "hpnd-inria-imag",
+    "hpnd-intel",
+    "hpnd-kevlin-henney",
+    "hpnd-markus-kuhn",
+    "hpnd-merchantability-variant",
+    "hpnd-mit-disclaimer",
+    "hpnd-netrek",
+    "hpnd-pbmplus",
+    "hpnd-sell-mit-disclaimer-xserver",
+    "hpnd-sell-regexpr",
+    "hpnd-sell-variant",
+    "hpnd-sell-variant-mit-disclaimer",
+    "hpnd-sell-variant-mit-disclaimer-rev",
+    "hpnd-uc",
+    "hpnd-uc-export-us",
+    "htmltidy",
+    "ibm-pibs",
+    "icu",
+    "iec-code-components-eula",
+    "ijg",
+    "ijg-short",
+    "imagemagick",
+    "imatix",
+    "imlib2",
+    "info-zip",
+    "inner-net-2.0",
+    "innosetup",
+    "intel",
+    "intel-acpi",
+    "interbase-1.0",
+    "ipa",
+    "ipl-1.0",
+    "isc",
+    "isc-veillard",
+    "jam",
+    "jasper-2.0",
+    "jpl-image",
+    "jpnic",
+    "json",
+    "kastrup",
+    "kazlib",
+    "knuth-ctan",
+    "lal-1.2",
+    "lal-1.3",
+    "latex2e",
+    "latex2e-translated-notice",
+    "leptonica",
+    "lgpl-2.0",
+    "lgpl-2.0+",
+    "lgpl-2.0-only",
+    "lgpl-2.0-or-later",
+    "lgpl-2.1",
+    "lgpl-2.1+",
+    "lgpl-2.1-only",
+    "lgpl-2.1-or-later",
+    "lgpl-3.0",
+    "lgpl-3.0+",
+    "lgpl-3.0-only",
+    "lgpl-3.0-or-later",
+    "lgpllr",
+    "libpng",
+    "libpng-2.0",
+    "libselinux-1.0",
+    "libtiff",
+    "libutil-david-nugent",
+    "liliq-p-1.1",
+    "liliq-r-1.1",
+    "liliq-rplus-1.1",
+    "linux-man-pages-1-para",
+    "linux-man-pages-copyleft",
+    "linux-man-pages-copyleft-2-para",
+    "linux-man-pages-copyleft-var",
+    "linux-openib",
+    "loop",
+    "lpd-document",
+    "lpl-1.0",
+    "lpl-1.02",
+    "lppl-1.0",
+    "lppl-1.1",
+    "lppl-1.2",
+    "lppl-1.3a",
+    "lppl-1.3c",
+    "lsof",
+    "lucida-bitmap-fonts",
+    "lzma-sdk-9.11-to-9.20",
+    "lzma-sdk-9.22",
+    "mackerras-3-clause",
+    "mackerras-3-clause-acknowledgment",
+    "magaz",
+    "mailprio",
+    "makeindex",
+    "martin-birgmeier",
+    "mcphee-slideshow",
+    "metamail",
+    "minpack",
+    "mips",
+    "miros",
+    "mit",
+    "mit-0",
+    "mit-advertising",
+    "mit-click",
+    "mit-cmu",
+    "mit-enna",
+    "mit-feh",
+    "mit-festival",
+    "mit-khronos-old",
+    "mit-modern-variant",
+    "mit-open-group",
+    "mit-testregex",
+    "mit-wu",
+    "mitnfa",
+    "mmixware",
+    "motosoto",
+    "mpeg-ssg",
+    "mpi-permissive",
+    "mpich2",
+    "mpl-1.0",
+    "mpl-1.1",
+    "mpl-2.0",
+    "mpl-2.0-no-copyleft-exception",
+    "mplus",
+    "ms-lpl",
+    "ms-pl",
+    "ms-rl",
+    "mtll",
+    "mulanpsl-1.0",
+    "mulanpsl-2.0",
+    "multics",
+    "mup",
+    "naist-2003",
+    "nasa-1.3",
+    "naumen",
+    "nbpl-1.0",
+    "ncbi-pd",
+    "ncgl-uk-2.0",
+    "ncl",
+    "ncsa",
+    "net-snmp",
+    "netcdf",
+    "newsletr",
+    "ngpl",
+    "nicta-1.0",
+    "nist-pd",
+    "nist-pd-fallback",
+    "nist-software",
+    "nlod-1.0",
+    "nlod-2.0",
+    "nlpl",
+    "nokia",
+    "nosl",
+    "noweb",
+    "npl-1.0",
+    "npl-1.1",
+    "nposl-3.0",
+    "nrl",
+    "ntp",
+    "ntp-0",
+    "nunit",
+    "o-uda-1.0",
+    "oar",
+    "occt-pl",
+    "oclc-2.0",
+    "odbl-1.0",
+    "odc-by-1.0",
+    "offis",
+    "ofl-1.0",
+    "ofl-1.0-no-rfn",
+    "ofl-1.0-rfn",
+    "ofl-1.1",
+    "ofl-1.1-no-rfn",
+    "ofl-1.1-rfn",
+    "ogc-1.0",
+    "ogdl-taiwan-1.0",
+    "ogl-canada-2.0",
+    "ogl-uk-1.0",
+    "ogl-uk-2.0",
+    "ogl-uk-3.0",
+    "ogtsl",
+    "oldap-1.1",
+    "oldap-1.2",
+    "oldap-1.3",
+    "oldap-1.4",
+    "oldap-2.0",
+    "oldap-2.0.1",
+    "oldap-2.1",
+    "oldap-2.2",
+    "oldap-2.2.1",
+    "oldap-2.2.2",
+    "oldap-2.3",
+    "oldap-2.4",
+    "oldap-2.5",
+    "oldap-2.6",
+    "oldap-2.7",
+    "oldap-2.8",
+    "olfl-1.3",
+    "oml",
+    "openpbs-2.3",
+    "openssl",
+    "openssl-standalone",
+    "openvision",
+    "opl-1.0",
+    "opl-uk-3.0",
+    "opubl-1.0",
+    "oset-pl-2.1",
+    "osl-1.0",
+    "osl-1.1",
+    "osl-2.0",
+    "osl-2.1",
+    "osl-3.0",
+    "padl",
+    "parity-6.0.0",
+    "parity-7.0.0",
+    "pddl-1.0",
+    "php-3.0",
+    "php-3.01",
+    "pixar",
+    "pkgconf",
+    "plexus",
+    "pnmstitch",
+    "polyform-noncommercial-1.0.0",
+    "polyform-small-business-1.0.0",
+    "postgresql",
+    "ppl",
+    "psf-2.0",
+    "psfrag",
+    "psutils",
+    "python-2.0",
+    "python-2.0.1",
+    "python-ldap",
+    "qhull",
+    "qpl-1.0",
+    "qpl-1.0-inria-2004",
+    "radvd",
+    "rdisc",
+    "rhecos-1.1",
+    "rpl-1.1",
+    "rpl-1.5",
+    "rpsl-1.0",
+    "rsa-md",
+    "rscpl",
+    "ruby",
+    "ruby-pty",
+    "sax-pd",
+    "sax-pd-2.0",
+    "saxpath",
+    "scea",
+    "schemereport",
+    "sendmail",
+    "sendmail-8.23",
+    "sendmail-open-source-1.1",
+    "sgi-b-1.0",
+    "sgi-b-1.1",
+    "sgi-b-2.0",
+    "sgi-opengl",
+    "sgp4",
+    "shl-0.5",
+    "shl-0.51",
+    "simpl-2.0",
+    "sissl",
+    "sissl-1.2",
+    "sl",
+    "sleepycat",
+    "smail-gpl",
+    "smlnj",
+    "smppl",
+    "snia",
+    "snprintf",
+    "softsurfer",
+    "soundex",
+    "spencer-86",
+    "spencer-94",
+    "spencer-99",
+    "spl-1.0",
+    "ssh-keyscan",
+    "ssh-openssh",
+    "ssh-short",
+    "ssleay-standalone",
+    "sspl-1.0",
+    "standardml-nj",
+    "sugarcrm-1.1.3",
+    "sun-ppp",
+    "sun-ppp-2000",
+    "sunpro",
+    "swl",
+    "swrule",
+    "symlinks",
+    "tapr-ohl-1.0",
+    "tcl",
+    "tcp-wrappers",
+    "termreadkey",
+    "tgppl-1.0",
+    "thirdeye",
+    "threeparttable",
+    "tmate",
+    "torque-1.1",
+    "tosl",
+    "tpdl",
+    "tpl-1.0",
+    "trustedqsl",
+    "ttwl",
+    "ttyp0",
+    "tu-berlin-1.0",
+    "tu-berlin-2.0",
+    "ubuntu-font-1.0",
+    "ucar",
+    "ucl-1.0",
+    "ulem",
+    "umich-merit",
+    "unicode-3.0",
+    "unicode-dfs-2015",
+    "unicode-dfs-2016",
+    "unicode-tou",
+    "unixcrypt",
+    "unlicense",
+    "upl-1.0",
+    "urt-rle",
+    "vim",
+    "vostrom",
+    "vsl-1.0",
+    "w3c",
+    "w3c-19980720",
+    "w3c-20150513",
+    "w3m",
+    "watcom-1.0",
+    "widget-workshop",
+    "wsuipa",
+    "wtfpl",
+    "wwl",
+    "wxwindows",
+    "x11",
+    "x11-distribute-modifications-variant",
+    "x11-swapped",
+    "xdebug-1.03",
+    "xerox",
+    "xfig",
+    "xfree86-1.1",
+    "xinetd",
+    "xkeyboard-config-zinoviev",
+    "xlock",
+    "xnet",
+    "xpp",
+    "xskat",
+    "xzoom",
+    "ypl-1.0",
+    "ypl-1.1",
+    "zed",
+    "zeeff",
+    "zend-2.0",
+    "zimbra-1.3",
+    "zimbra-1.4",
+    "zlib",
+    "zlib-acknowledgement",
+    "zpl-1.1",
+    "zpl-2.0",
+    "zpl-2.1"
+}


Test patch:
diff --git a/test/functional/sbom/test_cyclonedx.py b/test/functional/sbom/test_cyclonedx.py
index e8726bbbb..a6ca198da 100644
--- a/test/functional/sbom/test_cyclonedx.py
+++ b/test/functional/sbom/test_cyclonedx.py
@@ -133,6 +133,26 @@ class TestCyclonedx:
         content = json.loads(tc.load(cyclone_path))
         assert len(content["components"][0]["licenses"]) == n
 
+    @pytest.mark.parametrize("l, keys", [('"Mit"', ["id"]), ('"custom_license name"', ["name"]), ('("mIT", "custom")', ["id", "name"])])
+    def test_license_spdx_valid(self, hook_setup_post_package, l, keys):
+        tc = hook_setup_post_package
+        conanfile = textwrap.dedent(f"""
+                from conan import ConanFile
+                class HelloConan(ConanFile):
+                    name = 'foo'
+                    version = '1.0'
+                    license = {l}
+            """)
+        tc.save({"conanfile.py": conanfile})
+        tc.run("create .")
+        create_layout = tc.created_layout()
+        cyclone_path = os.path.join(create_layout.metadata(), "sbom.cdx.json")
+        content = json.loads(tc.load(cyclone_path))
+        for i, l in enumerate(content["components"][0]["licenses"]):
+            assert next(iter(l["license"])) == keys[i]
+
+
+
     def test_sbom_generation_no_tool_requires(self, hook_setup_post_package_no_tool_requires):
         tc = hook_setup_post_package_no_tool_requires
         tc.save({"app/conanfile.py": GenConanfile("app", "1.0")