diff --git a/schema/bom-1.7.proto b/schema/bom-1.7.proto index 3686422b..b8c205af 100644 --- a/schema/bom-1.7.proto +++ b/schema/bom-1.7.proto @@ -122,7 +122,7 @@ message Component { optional Scope scope = 11; // The hashes of the component. repeated Hash hashes = 12; - // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) + // A list of SPDX licenses and/or named licenses and/or SPDX License Expression. repeated LicenseChoice licenses = 13; // An optional copyright notice informing users of the underlying claims to copyright ownership in a published work. optional string copyright = 14; @@ -572,7 +572,7 @@ message Metadata { // The organization that supplied the component that the BOM describes. The supplier may often be the manufacture, but may also be a distributor or repackager. optional OrganizationalEntity supplier = 6; // The license information for the BOM document. This may be different from the license(s) of the component(s) that the BOM describes. - // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) + // A list of SPDX licenses and/or named licenses and/or SPDX License Expression. repeated LicenseChoice licenses = 7; // Specifies optional, custom, properties repeated Property properties = 8; @@ -709,7 +709,7 @@ message Service { optional bool x_trust_boundary = 9; // Specifies information about the data including the directional flow of data and the data classification. repeated DataFlow data = 10; - // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) + // A list of SPDX licenses and/or named licenses and/or SPDX License Expression. repeated LicenseChoice licenses = 11; // Provides the ability to document external references related to the service. repeated ExternalReference external_references = 12; @@ -831,7 +831,7 @@ message EvidenceCopyright { // Provides the ability to document evidence collected through various forms of extraction or analysis. message Evidence { - // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) + // A list of SPDX licenses and/or named licenses and/or SPDX License Expression. repeated LicenseChoice licenses = 1; // Copyright evidence captures intellectual property assertions, providing evidence of possible ownership and legal protection. repeated EvidenceCopyright copyright = 2; diff --git a/schema/bom-1.7.schema.json b/schema/bom-1.7.schema.json index 1bdcad7b..fd13dc5a 100644 --- a/schema/bom-1.7.schema.json +++ b/schema/bom-1.7.schema.json @@ -1525,36 +1525,31 @@ }, "licenseChoice": { "title": "License Choice", - "description": "EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression)", + "description": "A list of SPDX licenses and/or named licenses and/or SPDX License Expression.", "type": "array", - "oneOf": [ - { - "title": "Multiple licenses", - "description": "A list of SPDX licenses and/or named licenses.", - "type": "array", - "items": { + "items": { + "oneOf": [ + { "type": "object", "title": "License", - "required": ["license"], + "required": [ + "license" + ], "additionalProperties": false, "properties": { - "license": {"$ref": "#/definitions/license"} + "license": { + "$ref": "#/definitions/license" + } } - } - }, - { - "title": "SPDX License Expression", - "description": "A tuple of exactly one SPDX License Expression.", - "type": "array", - "additionalItems": false, - "minItems": 1, - "maxItems": 1, - "items": [{ + }, + { "title": "License Expression", "description": "Specifies the details and attributes related to a software license.\nIt must be a valid SPDX license expression, along with additional properties such as license acknowledgment.", "type": "object", "additionalProperties": false, - "required": ["expression"], + "required": [ + "expression" + ], "properties": { "expression": { "type": "string", @@ -1600,7 +1595,9 @@ "type": "string", "title": "License URL", "description": "The URL to the license file. If specified, a 'license' externalReference should also be specified for completeness", - "examples": ["https://www.apache.org/licenses/LICENSE-2.0.txt"], + "examples": [ + "https://www.apache.org/licenses/LICENSE-2.0.txt" + ], "format": "iri-reference" } }, @@ -1615,17 +1612,21 @@ "title": "BOM Reference", "description": "An optional identifier which can be used to reference the license elsewhere in the BOM. Every bom-ref must be unique within the BOM.\nValue SHOULD not start with the BOM-Link intro 'urn:cdx:' to avoid conflicts with BOM-Links." }, - "licensing": {"$ref": "#/definitions/licensing"}, + "licensing": { + "$ref": "#/definitions/licensing" + }, "properties": { "type": "array", "title": "Properties", "description": "Provides the ability to document properties in a name-value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. Unlike key-value stores, properties support duplicate names, each potentially having different values. Property names of interest to the general public are encouraged to be registered in the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). Formal registration is optional.", - "items": {"$ref": "#/definitions/property"} + "items": { + "$ref": "#/definitions/property" + } } } - }] - } - ] + } + ] + } }, "commit": { "type": "object", diff --git a/schema/bom-1.7.xsd b/schema/bom-1.7.xsd index fbf9e774..dc8cb4d0 100644 --- a/schema/bom-1.7.xsd +++ b/schema/bom-1.7.xsd @@ -2553,10 +2553,13 @@ limitations under the License. - - - - + + A list of SPDX licenses and/or named licenses and/or SPDX License Expression. + + + + + diff --git a/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.json b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.json new file mode 100644 index 00000000..7c6813c1 --- /dev/null +++ b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:df628836-6b9b-41c9-a724-b44743c54d42", + "version": 1, + "metadata": { + "lifecycles": [{"phase": "design"}] + }, + "components": [ + { + "type": "library", + "group": "com.example", + "name": "situation-A", + "version": "1", + "description": "Multiple licenses: declared ids/names, and a concluded expression", + "licenses": [ + { + "license": { + "id": "MIT", + "acknowledgement": "declared" + } + }, + { + "license": { + "id": "PostgreSQL", + "acknowledgement": "declared" + } + }, + { + "license": { + "name": "Apache Software License", + "acknowledgement": "declared" + } + }, + { + "expression": "(MIT OR PostgreSQL OR Apache-2.0)", + "acknowledgement": "concluded" + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-B", + "version": "1", + "description": "Multiple license expressions: one declared, one concluded", + "licenses": [ + { + "expression": "MIT OR (GPL-3.0 OR GPL-2.0)", + "acknowledgement": "declared" + }, + { + "expression": "(GPL-3.0-only AND LGPL-2.0-only)", + "acknowledgement": "concluded" + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-C", + "version": "1", + "description": "Multiple license: one declared expression, one concluded id", + "licenses": [ + { + "expression": "GPL-3.0-or-later OR GPL-2.0", + "acknowledgement": "declared" + }, + { + "license": { + "id": "GPL-3.0-only", + "acknowledgement": "concluded" + } + } + ] + } + ] +} diff --git a/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.xml b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.xml new file mode 100644 index 00000000..849ad97b --- /dev/null +++ b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.xml @@ -0,0 +1,46 @@ + + + + + design + + + + com.example + situation-A + 1 + Multiple licenses: declared ids/names, and a concluded expression + + MIT + PostgreSQL + Apache Software License + (MIT OR PostgreSQL OR Apache-2.0) + + + + com.example + situation-B + 1 + Multiple license expressions: one declared, one concluded + + MIT OR (GPL-3.0 OR GPL-2.0) + (GPL-3.0-only AND LGPL-2.0-only) + + + + com.example + situation-C + 1 + Multiple license: one declared expression, one concluded id + + GPL-3.0-or-later OR GPL-2.0 + GPL-3.0-only + + + + diff --git a/tools/src/test/resources/1.7/valid-license-choice-1.7.json b/tools/src/test/resources/1.7/valid-license-choice-1.7.json new file mode 100644 index 00000000..d711dfeb --- /dev/null +++ b/tools/src/test/resources/1.7/valid-license-choice-1.7.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "description": "Modified version of Apache Catalina", + "scope": "required", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + }, + { + "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0" + }, + { + "license": { + "name": "My Own License", + "text": { + "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + } + } + }, + { + "expression": "LicenseRef-MIT-Style-2", + "expressionDetails": [ + { + "licenseIdentifier": "LicenseRef-MIT-Style-2", + "url": "https://example.com/license" + } + ] + } + ] + } + ] +} diff --git a/tools/src/test/resources/1.7/valid-license-choice-1.7.textproto b/tools/src/test/resources/1.7/valid-license-choice-1.7.textproto new file mode 100644 index 00000000..3102465d --- /dev/null +++ b/tools/src/test/resources/1.7/valid-license-choice-1.7.textproto @@ -0,0 +1,43 @@ +# proto-file: schema/bom-1.7.proto +# proto-message: Bom + +# All license posture in here is for show-case ony. +# This is not a real law-case! + +spec_version: "1.7" +serial_number: "urn:uuid:b1ef52c6-7cd8-43d5-9e42-5e69044bbe9e" +version: 1 +components { + type: CLASSIFICATION_APPLICATION + publisher: "Acme Inc" + group: "com.acme" + name: "tomcat-catalina" + version: "9.0.14" + description: "Modified version of Apache Catalina" + scope: SCOPE_REQUIRED + licenses { + license { + id: "Apache-2.0" + } + } + licenses { + expression: "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0" + } + licenses { + license { + name: "My Own License" + text { + value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + } + } + } + licenses { + expression_detailed { + expression: "LicenseRef-MIT-Style-2" + details { + license_identifier: "LicenseRef-MIT-Style-2" + url: "https://example.com/license" + } + } + } +} diff --git a/tools/src/test/resources/1.7/invalid-license-choice-1.7.xml b/tools/src/test/resources/1.7/valid-license-choice-1.7.xml similarity index 50% rename from tools/src/test/resources/1.7/invalid-license-choice-1.7.xml rename to tools/src/test/resources/1.7/valid-license-choice-1.7.xml index fec014d5..e3cca7ac 100644 --- a/tools/src/test/resources/1.7/invalid-license-choice-1.7.xml +++ b/tools/src/test/resources/1.7/valid-license-choice-1.7.xml @@ -1,5 +1,8 @@ - + Acme Inc @@ -8,17 +11,20 @@ 9.0.14 Modified version of Apache Catalina required - - 3942447fac867ae5cdb3229b658f4d48 - e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a - f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b - e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 - Apache-2.0 EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + My Own License + + + +
+ https://example.com/license +
+
pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
diff --git a/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.json b/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.json new file mode 100644 index 00000000..29ba6d58 --- /dev/null +++ b/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.json @@ -0,0 +1,163 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:df628836-6b9b-41c9-a724-b44743c54d42", + "version": 1, + "metadata": { + "lifecycles": [{"phase": "design"}] + }, + "components": [ + { + "type": "library", + "group": "com.example", + "name": "situation-A", + "version": "1", + "description": "Multiple licenses: declared ids/names, and a concluded expression", + "licenses": [ + { + "license": { + "id": "MIT", + "acknowledgement": "declared" + } + }, + { + "license": { + "id": "PostgreSQL", + "acknowledgement": "declared" + } + }, + { + "license": { + "name": "Apache Software License", + "acknowledgement": "declared" + } + }, + { + "expression": "(MIT OR PostgreSQL OR Apache-2.0)", + "acknowledgement": "concluded" + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-B", + "version": "1", + "description": "Multiple license expressions: one declared, one concluded", + "licenses": [ + { + "expression": "MIT OR (GPL-3.0 OR GPL-2.0)", + "acknowledgement": "declared" + }, + { + "expression": "(GPL-3.0-only AND LGPL-2.0-only)", + "acknowledgement": "concluded" + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-C", + "version": "1", + "description": "Multiple license: one declared expression, one concluded id", + "licenses": [ + { + "expression": "GPL-3.0-or-later OR GPL-2.0", + "acknowledgement": "declared" + }, + { + "license": { + "id": "GPL-3.0-only", + "acknowledgement": "concluded" + } + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-D", + "version": "1", + "description": "Multiple license with texts: one declared expression, one concluded id", + "licenses": [ + { + "expression": "GPL-3.0-or-later OR GPL-2.0", + "acknowledgement": "declared", + "expressionDetails": [ + { + "licenseIdentifier": "GPL-3.0-or-later", + "text": { + "content": "specific GPL-3.0-or-later license text" + } + }, + { + "licenseIdentifier": "GPL-2.0", + "text": { + "content": "specific GPL-2.0 license text" + } + } + ] + }, + { + "license": { + "id": "GPL-3.0-only", + "acknowledgement": "concluded", + "text": { + "content": "specific GPL-3.0-or-later license text" + } + } + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-E", + "version": "1", + "description": "Multiple licenses with urls: declared ids/names, and a concluded expression", + "licenses": [ + { + "license": { + "id": "MIT", + "acknowledgement": "declared", + "url": "https://example.com/licenses/MIT" + } + }, + { + "license": { + "id": "PostgreSQL", + "acknowledgement": "declared", + "url": "https://example.com/licenses/PostgreSQL" + } + }, + { + "license": { + "name": "Apache Software License", + "acknowledgement": "declared", + "url": "https://example.com/licenses/Apache-2.0" + } + }, + { + "expression": "(MIT AND PostgreSQL AND Apache-2.0)", + "acknowledgement": "concluded", + "expressionDetails": [ + { + "licenseIdentifier": "MIT", + "url": "https://example.com/licenses/MIT" + }, + { + "licenseIdentifier": "PostgreSQL", + "url": "https://example.com/licenses/PostgreSQL" + }, + { + "licenseIdentifier": "Apache-2.0", + "url": "https://example.com/licenses/Apache-2.0" + } + ] + } + ] + } + ] +} diff --git a/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.textproto b/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.textproto new file mode 100644 index 00000000..41c2a861 --- /dev/null +++ b/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.textproto @@ -0,0 +1,154 @@ +# proto-file: schema/bom-1.7.proto +# proto-message: Bom + +# All license posture in here is for show-case ony. +# This is not a real law-case! + +spec_version: "1.7" +version: 1 +serial_number: "urn:uuid:df628836-6b9b-41c9-a724-b44743c54d42" +metadata: { + lifecycles { phase: LIFECYCLE_PHASE_DESIGN } +} +components { + type: CLASSIFICATION_LIBRARY + group: "com.example" + name: "situation-A" + version: "1" + description: "Multiple licenses: declared ids/names, and a concluded expression" + licenses { + license { + id: "MIT" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + } + licenses { + license { + id: "PostgreSQL" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + } + licenses { + license { + name: "Apache Software License" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + } + licenses { + expression: "(MIT OR PostgreSQL OR Apache-2.0)" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_CONCLUDED + } +} +components { + type: CLASSIFICATION_LIBRARY + group: "com.example" + name: "situation-B" + version: "1" + description: "Multiple license expressions: one declared, one concluded" + licenses { + expression: "MIT OR (GPL-3.0 OR GPL-2.0)" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + licenses { + expression: "(GPL-3.0-only AND LGPL-2.0-only)" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_CONCLUDED + } +} +components { + type: CLASSIFICATION_LIBRARY + group: "com.example" + name: "situation-C" + version: "1" + description: "Multiple license: one declared expression, one concluded id" + licenses { + expression: "GPL-3.0-or-later OR GPL-2.0" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + licenses { + license { + id: "GPL-3.0-only" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_CONCLUDED + } + } +} +components { + type: CLASSIFICATION_LIBRARY + group: "com.example" + name: "situation-D" + version: "1" + description: "Multiple license with texts: one declared expression, one concluded id" + licenses { + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + expression_detailed { + expression: "GPL-3.0-or-later OR GPL-2.0" + details { + license_identifier: "GPL-3.0-or-later" + text { + value: "specific GPL-3.0-or-later license text" + } + } + details { + license_identifier: "GPL-2.0" + text { + value: "specific GPL-2.0 license text" + } + } + } + } + licenses { + license: { + id: "GPL-3.0-only" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_CONCLUDED + text { + value: "specific GPL-3.0-or-later license text" + } + } + } +} + +components { + type: CLASSIFICATION_LIBRARY + group: "com.example" + name: "situation-E" + version: "1" + description: "Multiple licenses with urls: declared ids/names, and a concluded expression" + licenses { + license { + id: "MIT" + url: "https://example.com/licenses/MIT" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + } + licenses { + license { + id: "PostgreSQL" + url: "https://example.com/licenses/PostgreSQL" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + } + licenses { + license { + name: "Apache Software License" + url: "https://example.com/licenses/Apache-2.0" + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + } + } + licenses { + expression_detailed { + acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_CONCLUDED + expression: "(MIT AND PostgreSQL AND Apache-2.0)" + details { + license_identifier: "MIT" + url: "https://example.com/licenses/MIT" + } + details { + license_identifier: "PostgreSQL" + url: "https://example.com/licenses/PostgreSQL" + } + details { + license_identifier: "Apache-2.0" + url: "https://example.com/licenses/Apache-2.0" + } + } + } +} diff --git a/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.xml b/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.xml new file mode 100644 index 00000000..9b35f5cf --- /dev/null +++ b/tools/src/test/resources/1.7/valid-license-declared-concluded-mix-1.7.xml @@ -0,0 +1,115 @@ + + + + + + + design + + + + + + com.example + situation-A + 1 + Multiple licenses: declared ids/names, and a concluded expression + + + MIT + + + PostgreSQL + + + Apache Software License + + (MIT OR PostgreSQL OR Apache-2.0) + + + + com.example + situation-B + 1 + Multiple license expressions: one declared, one concluded + + MIT OR (GPL-3.0 OR GPL-2.0) + (GPL-3.0-only AND LGPL-2.0-only) + + + + com.example + situation-C + 1 + Multiple license: one declared expression, one concluded id + + GPL-3.0-or-later OR GPL-2.0 + + GPL-3.0-only + + + + + com.example + situation-D + 1 + Multiple license with texts: one declared expression, one concluded id + + +
+ specific GPL-3.0-or-later license text +
+
+ specific GPL-2.0 license text +
+
+ + GPL-3.0-only + specific GPL-3.0-or-later license text + +
+
+ + com.example + situation-E + 1 + Multiple licenses with urls: declared ids/names, and a concluded expression + + + MIT + https://example.com/licenses/MIT + + + PostgreSQL + https://example.com/licenses/PostgreSQL + + + Apache Software License + https://example.com/licenses/Apache-2.0 + + +
+ https://example.com/licenses/MIT +
+
+ https://example.com/licenses/PostgreSQL +
+
+ https://example.com/licenses/Apache-2.0 +
+
+
+
+
+