diff --git a/schema/2.0/cyclonedx-2.0.schema.json b/schema/2.0/cyclonedx-2.0.schema.json index ecf571857..8e7573861 100644 --- a/schema/2.0/cyclonedx-2.0.schema.json +++ b/schema/2.0/cyclonedx-2.0.schema.json @@ -8,7 +8,6 @@ "specFormat", "specVersion" ], - "additionalProperties": false, "properties": { "$schema": { "type": "string" @@ -109,5 +108,6 @@ }, "allOf": [ { "$ref": "model/cyclonedx-common-2.0.schema.json#/$defs/extensibleProperties" } - ] + ], + "unevaluatedProperties": false } diff --git a/schema/2.0/model/cyclonedx-ai-modelcard-2.0.schema.json b/schema/2.0/model/cyclonedx-ai-modelcard-2.0.schema.json index 3fcf23c29..8eb6706fd 100644 --- a/schema/2.0/model/cyclonedx-ai-modelcard-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-ai-modelcard-2.0.schema.json @@ -373,7 +373,6 @@ "description": "A description of the energy provider." }, "organization": { - "type": "object", "title": "Organization", "description": "The organization that provides energy.", "$ref": "cyclonedx-common-2.0.schema.json#/$defs/organizationalEntity" diff --git a/schema/2.0/model/cyclonedx-annotation-2.0.schema.json b/schema/2.0/model/cyclonedx-annotation-2.0.schema.json index 83f9aa0aa..2866b987f 100644 --- a/schema/2.0/model/cyclonedx-annotation-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-annotation-2.0.schema.json @@ -55,17 +55,26 @@ { "required": [ "organization" - ] + ], + "properties": { + "organization": true + } }, { "required": [ "individual" - ] + ], + "properties": { + "individual": true + } }, { "required": [ "component" - ] + ], + "properties": { + "component": true + } } ], "additionalProperties": false, diff --git a/schema/2.0/model/cyclonedx-behavior-2.0.schema.json b/schema/2.0/model/cyclonedx-behavior-2.0.schema.json index 1e0ce375a..7f291348e 100644 --- a/schema/2.0/model/cyclonedx-behavior-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-behavior-2.0.schema.json @@ -222,10 +222,17 @@ "then": { "properties": { "nodes": { + "type": "array", "items": { "required": [ "ordinal" - ] + ], + "properties": { + "ordinal": true + }, + "additionalProperties": true, + "$comment": "additionalProperties explicitly allowed - this is just a minimal constraint", + "type": "object" } } } @@ -289,12 +296,12 @@ "description": "For an activity node, the behavior performed, drawn from the taxonomy. Mutually exclusive with 'ref' and 'graph'." }, "ref": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Behavior Reference", "description": "For an activity node, a reference to a behavior instance. Mutually exclusive with 'behavior' and 'graph'." }, "graph": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Graph Reference", "description": "A reference to a nested behavior graph. For an activity node it is the sub-process performed and is mutually exclusive with 'behavior' and 'ref'; for a composite node it is the nested region." }, @@ -339,17 +346,17 @@ } }, "onEntry": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "On Entry", "description": "For a state node, a reference to a behavior instance performed when the state is entered." }, "onExit": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "On Exit", "description": "For a state node, a reference to a behavior instance performed when the state is exited." }, "doActivity": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Do Activity", "description": "For a state node, a reference to a behavior instance performed while the subject remains in the state." } @@ -368,21 +375,9 @@ }, "then": { "oneOf": [ - { - "required": [ - "behavior" - ] - }, - { - "required": [ - "ref" - ] - }, - { - "required": [ - "graph" - ] - } + { "required": [ "behavior" ], "properties": { "behavior": true } }, + { "required": [ "ref" ], "properties": { "ref": true } }, + { "required": [ "graph" ], "properties": { "graph": true } } ] } } @@ -412,12 +407,12 @@ "description": "A description of the transition." }, "source": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Source", "description": "Reference to the source node." }, "target": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Target", "description": "Reference to the target node." }, @@ -435,7 +430,7 @@ "description": "Whether this transition is taken when no other guard from the same source node holds." }, "effect": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Effect", "description": "Reference to a behavior instance performed when the transition fires." } diff --git a/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json b/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json index 6c1d4d324..28a4937b0 100644 --- a/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json @@ -153,6 +153,7 @@ "uniqueItems": true, "items": { "type": "object", + "additionalProperties": false, "properties": { "ref": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", @@ -586,7 +587,11 @@ "required": [ "bom-ref", "componentRef" - ] + ], + "properties": { + "bom-ref": true, + "componentRef": true + } }, { "title": "Party Reference Asset", @@ -594,7 +599,11 @@ "required": [ "bom-ref", "partyRef" - ] + ], + "properties": { + "bom-ref": true, + "partyRef": true + } }, { "title": "Inline Asset", @@ -603,7 +612,12 @@ "bom-ref", "type", "name" - ] + ], + "properties": { + "bom-ref": true, + "type": true, + "name": true + } } ] }, @@ -1298,51 +1312,15 @@ "ref" ], "oneOf": [ - { - "required": [ - "aggregates" - ] - }, - { - "required": [ - "associates" - ] - }, - { - "required": [ - "composes" - ] - }, - { - "required": [ - "contains" - ] - }, - { - "required": [ - "dependsOn" - ] - }, - { - "required": [ - "generalizes" - ] - }, - { - "required": [ - "realizes" - ] - }, - { - "required": [ - "serves" - ] - }, - { - "required": [ - "custom" - ] - } + { "required": [ "aggregates" ], "properties": { "aggregates": true } }, + { "required": [ "associates" ], "properties": { "associates": true } }, + { "required": [ "composes" ], "properties": { "composes": true } }, + { "required": [ "contains" ], "properties": { "contains": true } }, + { "required": [ "dependsOn" ], "properties": { "dependsOn": true } }, + { "required": [ "generalizes" ], "properties": { "generalizes": true } }, + { "required": [ "realizes" ], "properties": { "realizes": true } }, + { "required": [ "serves" ], "properties": { "serves": true } }, + { "required": [ "custom" ], "properties": { "custom": true } } ], "properties": { "ref": { @@ -1846,13 +1824,13 @@ } }, "visualizationType": { - "type": "object", "title": "Visualization Type", "description": "The type of diagram or visual representation.", "oneOf": [ { "title": "Predefined Visualization Type", "description": "A visualization type selected from a predefined set of well-known diagram types.", + "type": "object", "required": [ "type" ], @@ -1915,6 +1893,7 @@ { "title": "Custom Visualization Type", "description": "A custom visualization type not covered by the predefined enumeration.", + "type": "object", "required": [ "name" ], diff --git a/schema/2.0/model/cyclonedx-citation-2.0.schema.json b/schema/2.0/model/cyclonedx-citation-2.0.schema.json index b08f2856b..f917370c4 100644 --- a/schema/2.0/model/cyclonedx-citation-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-citation-2.0.schema.json @@ -73,12 +73,24 @@ }, "required": ["timestamp"], "anyOf": [ - { "required": ["attributedTo"] }, - { "required": ["process"] } + { + "properties": { "attributedTo": true }, + "required": ["attributedTo"] + }, + { + "properties": { "process": true }, + "required": ["process"] + } ], "oneOf": [ - { "required": ["pointers"] }, - { "required": ["expressions"] } + { + "properties": { "pointers": true }, + "required": ["pointers"] + }, + { + "properties": { "expressions": true }, + "required": ["expressions"] + } ] } } diff --git a/schema/2.0/model/cyclonedx-common-2.0.schema.json b/schema/2.0/model/cyclonedx-common-2.0.schema.json index 71174e76e..88658a6a5 100644 --- a/schema/2.0/model/cyclonedx-common-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-common-2.0.schema.json @@ -13,7 +13,8 @@ }, "refLinkType": { "description": "Descriptor for an element identified by the attribute 'bom-ref' in the same BOM document.\nIn contrast to `bomLinkElementType`.", - "$ref": "#/$defs/refType" + "allOf": [{ "$ref": "#/$defs/refType" }], + "$comment": "value-range is same as 'refType'" }, "bomLinkDocumentType": { "title": "BOM-Link Document", @@ -421,7 +422,7 @@ } }, "organizationalEntityOrContact": { - + "$comment": "TODO" }, "origin": { "type": "object", @@ -580,43 +581,70 @@ "extensibleProperties": { "type": "object", "title": "Extensible Properties", + "$comment": "This is a mixin. It intentionally does NOT restrict additional/unevaluated properties itself; schemas composing it via `allOf` are expected to close themselves with `unevaluatedProperties: false` so that both their own defined properties and these patternProperties remain usable.", "patternProperties": { "^ext:[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}:.+$": { - "description": "CycloneDX supports a structured and namespace-aware mechanism for extensibility through the use of extensible properties. This mechanism enables organizations, ecosystems, and tool vendors to safely introduce custom properties without conflicting with the core schema or other extensions.\n\nExtensible properties are defined as a JSON object whose keys must conform to a strict pattern that resembles a reverse domain name structure, prefixed with ext:. This pattern provides a namespacing convention that aligns with well-established practices in other structured formats (e.g., XML namespaces).", + "description": "CycloneDX supports a structured and namespace-aware mechanism for extensibility through the use of extensible properties. This mechanism enables organizations, ecosystems, and tool vendors to safely introduce custom properties without conflicting with the core schema or other extensions.\n\nExtensible properties are defined as a JSON object whose keys must conform to a strict pattern that resembles a reverse domain name structure, prefixed with ext:. This pattern provides a namespacing convention that aligns with well-established practices in other structured formats (e.g., XML namespaces).\n\nValues that are objects must declare the schema they conform to via `$schema`. This requirement applies recursively to objects contained in arrays, at any nesting depth.", "examples": [ "ext::", "ext:example.org:myExtension" ], + "$ref": "#/$defs/extensibleProperties/$defs/propertyValue" + } + }, + "$defs": { + "propertyObject": { + "type": "object", + "title": "Extensible Property Object", + "$comment": "Internal helper for extensibleProperties. Not part of the public schema API — do not reference externally; may change without notice.\n\nadditionalProperties explicitly allowed for extensibility reasons.", + "required": ["$schema"], + "properties": { + "$schema": { + "type": "string", + "format": "uri" + } + }, + "additionalProperties": true + }, + "propertyValue": { + "title": "Extensible Property Value", + "$comment": "Internal helper for extensibleProperties. Not part of the public schema API — do not reference externally; may change without notice.\nRecursive: objects must declare a `$schema`, arrays may nest arbitrarily deep with the same rule applied to every item, all other values are plain scalars.", "if": { - "type": ["object", "array"] + "type": "object" }, "then": { - "type": "object", - "required": ["$schema"], - "properties": { - "$schema": { - "type": "string", - "format": "uri" - } - } + "$ref": "#/$defs/extensibleProperties/$defs/propertyObject" }, "else": { - "type": ["string", "number", "boolean", "null"] + "if": { + "type": "array" + }, + "then": { + "type": "array", + "items": { + "$ref": "#/$defs/extensibleProperties/$defs/propertyValue" + } + }, + "else": { + "type": ["string", "number", "boolean", "null"] + } } } } }, "baseObject": { + "type": "object", "description": "Base object for all CycloneDX entities. Automatically includes support for extensible properties.", + "$comment": "This is a mixin. It intentionally does NOT set `unevaluatedProperties: false` — that keyword cannot see properties defined by schemas composing this one via `allOf`, and would reject them. Concrete (leaf) schemas composing this mixin must close themselves with `unevaluatedProperties: false`.", "allOf": [ - { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/extensibleProperties" } + { "$ref": "#/$defs/extensibleProperties" } ], "properties": { "properties": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/properties" + "$ref": "#/$defs/properties" }, "externalReferences": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" + "$ref": "#/$defs/externalReferences" } } }, @@ -642,7 +670,6 @@ ] }, "lifecycle": { - "type": "object", "title": "Lifecycle", "description": "The product lifecycle(s) that this BOM represents.", "oneOf": [ @@ -650,6 +677,7 @@ "$ref": "#/$defs/preDefinedLifecyclePhase" }, { + "type": "object", "title": "Custom Lifecycle Phase", "required": ["name"], "additionalProperties": false, @@ -675,6 +703,7 @@ "items": { "$ref": "#/$defs/lifecycle"} }, "preDefinedLifecyclePhase": { + "type": "object", "title": "Pre-Defined Phase", "required": ["phase"], "additionalProperties": false, @@ -923,4 +952,4 @@ "description": "Enveloped signatures in [JSON Signature Scheme (JSS/ITU-T X.590)](https://www.itu.int/epublications/publication/itu-t-x-590-2023-10-json-signature-scheme-jss)." } } -} +} \ No newline at end of file diff --git a/schema/2.0/model/cyclonedx-component-2.0.schema.json b/schema/2.0/model/cyclonedx-component-2.0.schema.json index 15af320b6..451d18b60 100644 --- a/schema/2.0/model/cyclonedx-component-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-component-2.0.schema.json @@ -304,8 +304,9 @@ }, "allOf": [ { - "description": "Requirement: ensure that `version` and `versionRange` are not present simultaneously.", + "description": "Requirement: ensure that `version` and `versionRange` are mutually exclusive.", "not": { + "properties": { "version": true, "versionRange": true }, "required": ["version", "versionRange"] } }, @@ -371,8 +372,8 @@ "else": { "not": { "anyOf": [ - { "required": ["endpoints"] }, - { "required": ["dataProfiles"] } + { "required": ["endpoints"], "properties": { "endpoints": true } }, + { "required": ["dataProfiles"], "properties": { "dataProfiles": true } } ] } } @@ -524,8 +525,8 @@ "title": "License Evidence", "description": "A detected license, together with how it was detected, the confidence in the detection, the tools and parties involved, and where it was found.", "oneOf": [ - { "required": [ "license" ] }, - { "required": [ "expression" ] } + { "required": [ "license" ], "properties": { "license": true } }, + { "required": [ "expression" ], "properties": { "expression": true } } ], "additionalProperties": false, "properties": { diff --git a/schema/2.0/model/cyclonedx-cryptography-2.0.schema.json b/schema/2.0/model/cyclonedx-cryptography-2.0.schema.json index 1a073ea5b..cb5c00f17 100644 --- a/schema/2.0/model/cyclonedx-cryptography-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-cryptography-2.0.schema.json @@ -425,11 +425,11 @@ "title": "Certificate Lifecycle State", "description": "The certificate lifecycle is a comprehensive process that manages digital certificates from their initial creation to eventual expiration or revocation. It typically involves several stages.", "items": { - "type": "object", "title": "State", "description": "The state of the certificate.", "oneOf": [ { + "type": "object", "title": "Pre-Defined State", "required": [ "state" @@ -465,6 +465,7 @@ } }, { + "type": "object", "title": "Custom State", "required": [ "name" @@ -531,11 +532,11 @@ "title": "Certificate Extensions", "description": "A certificate extension is a field that provides additional information about the certificate or its use. Extensions are used to convey additional information beyond the standard fields.", "items": { - "type": "object", "title": "Extension", "description": "", "oneOf": [ { + "type": "object", "title": "Common Extensions", "required": [ "commonExtensionName", @@ -580,6 +581,7 @@ } }, { + "type": "object", "title": "Custom Extensions", "description": "Custom extensions may convey application-specific or vendor-specific data not covered by standard extensions. The structure and semantics of custom extensions are typically defined outside of public standards. CycloneDX leverages properties to support this capability.", "required": [ @@ -895,7 +897,7 @@ "title": "Related Algorithms", "description": "A list of algorithms related to the cipher suite.", "items": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Algorithm reference", "description": "The bom-ref to algorithm cryptographic asset." } @@ -965,7 +967,7 @@ "description": "The key length of the encryption algorithm." }, "algorithm": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Algorithm reference", "description": "The bom-ref to algorithm cryptographic asset." } @@ -986,7 +988,7 @@ ] }, "algorithm": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Algorithm reference", "description": "The bom-ref to algorithm cryptographic asset." } @@ -1007,7 +1009,7 @@ ] }, "algorithm": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Algorithm reference", "description": "The bom-ref to algorithm cryptographic asset." } @@ -1025,7 +1027,7 @@ "description": "A group identifier for the key exchange algorithm." }, "algorithm": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Algorithm reference", "description": "The bom-ref to algorithm cryptographic asset." } @@ -1043,7 +1045,7 @@ "description": "A name for the authentication method." }, "algorithm": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Algorithm reference", "description": "The bom-ref to algorithm cryptographic asset." } @@ -1166,18 +1168,18 @@ ] }, "ref": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType", + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType", "title": "Reference to cryptographic asset", "description": "The bom-ref to cryptographic asset." } } }, "fingerprint": { - "type": "object", "title": "Fingerprint", "description": "The fingerprint is a cryptographic hash of the asset.", "oneOf": [ { + "type": "object", "title": "Standard Hash", "description": "A fingerprint computed using a standard, well-known hash algorithm.", "required": ["alg", "content"], @@ -1192,6 +1194,7 @@ } }, { + "type": "object", "title": "Custom Fingerprint", "description": "A fingerprint computed with a custom or non-standard algorithm not covered by the standard hash algorithms.", "required": ["customAlg", "customContent"], @@ -1234,7 +1237,7 @@ "title": "References", "description": "The bom-refs to the assets securing this asset (e.g., algorithms, hardware, keys).", "items": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType" + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" } } } diff --git a/schema/2.0/model/cyclonedx-data-2.0.schema.json b/schema/2.0/model/cyclonedx-data-2.0.schema.json index fef796179..8e342a29f 100644 --- a/schema/2.0/model/cyclonedx-data-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-data-2.0.schema.json @@ -524,21 +524,11 @@ "additionalProperties": false, "anyOf": [ { - "required": [ - "name", - "type" - ] - }, - { - "required": [ - "party" - ] + "required": [ "name", "type" ], + "properties": { "name": true, "type": true } }, - { - "required": [ - "ref" - ] - } + { "required": [ "party" ], "properties": { "party": true } }, + { "required": [ "ref" ], "properties": { "ref": true } } ], "examples": [ { diff --git a/schema/2.0/model/cyclonedx-declaration-2.0.schema.json b/schema/2.0/model/cyclonedx-declaration-2.0.schema.json index e8ba2c294..2e1c3557b 100644 --- a/schema/2.0/model/cyclonedx-declaration-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-declaration-2.0.schema.json @@ -326,9 +326,11 @@ "additionalProperties": false, "oneOf": [ { - "required": ["signature"] + "properties": { "signatures": true }, + "required": ["signatures"] }, { + "properties": { "externalReference": true, "organization": true }, "required": ["externalReference", "organization"] } ], diff --git a/schema/2.0/model/cyclonedx-evidence-2.0.schema.json b/schema/2.0/model/cyclonedx-evidence-2.0.schema.json index 3d3039a42..dd7c86611 100644 --- a/schema/2.0/model/cyclonedx-evidence-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-evidence-2.0.schema.json @@ -273,6 +273,9 @@ "allOf": [ { "$ref": "#/$defs/analysisMethod" }, { + "type": "object", + "additionalProperties": true, + "$comment": "additionalProperties explicitly allowed - it is controlled by the other `allOf`", "properties": { "technique": { "not": { @@ -300,6 +303,9 @@ "allOf": [ { "$ref": "#/$defs/analysisMethod" }, { + "type": "object", + "additionalProperties": true, + "$comment": "additionalProperties explicitly allowed - it is controlled by the other `allOf`", "properties": { "technique": { "not": { diff --git a/schema/2.0/model/cyclonedx-formulation-2.0.schema.json b/schema/2.0/model/cyclonedx-formulation-2.0.schema.json index c68433646..2fb4d0a92 100644 --- a/schema/2.0/model/cyclonedx-formulation-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-formulation-2.0.schema.json @@ -630,24 +630,20 @@ "type": "object", "oneOf": [ { - "required": [ - "resource" - ] + "properties": { "resource": true }, + "required": [ "resource" ] }, { - "required": [ - "parameters" - ] + "properties": { "parameters": true }, + "required": ["parameters"] }, { - "required": [ - "environmentVars" - ] + "properties": { "environmentVars": true }, + "required": ["environmentVars"] }, { - "required": [ - "data" - ] + "properties": { "data": true }, + "required": ["data"] } ], "additionalProperties": false, @@ -720,19 +716,16 @@ "type": "object", "oneOf": [ { - "required": [ - "resource" - ] + "properties": { "resource": true }, + "required": ["resource"] }, { - "required": [ - "environmentVars" - ] + "properties": { "environmentVars": true }, + "required": ["environmentVars"] }, { - "required": [ - "data" - ] + "properties": { "data": true }, + "required": ["data"] } ], "additionalProperties": false, @@ -828,14 +821,12 @@ }, "oneOf": [ { - "required": [ - "ref" - ] + "properties": { "ref": true }, + "required": ["ref"] }, { - "required": [ - "externalReference" - ] + "properties": { "externalReference": true }, + "required": ["externalReference"] } ] }, diff --git a/schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json b/schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json index 205469977..6b90fc0e3 100644 --- a/schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json @@ -16,7 +16,20 @@ "2023-10-29T13:56:08Z", "2023-10-29T13:56:08.000Z", "2023-11-15T08:30:00.123Z" - ] + ], + "$defs": { + "withMilliseconds": { + "$comment": "Internal helper for timestamp. Not part of the public schema API — do not reference externally; may change without notice.", + "title": "Timestamp with Milliseconds", + "description": "An RFC 3339 timestamp in the UTC+0 time zone. Must use the 'Z' suffix. Sub-second precision MUST be exactly three digits (millisecond precision). Matches the pattern: yyyy-mm-ddThh:mm:ss.sssZ", + "type": "string", + "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\.[0-9][0-9][0-9]Z$", + "examples": [ + "2023-10-29T13:56:08.000Z", + "2023-11-15T08:30:00.123Z" + ] + } + } }, "identifier": { "title": "Identifier", @@ -192,18 +205,16 @@ "type": "string" }, "created": { - "$ref": "#/$defs/timestamp", + "$ref": "#/$defs/timestamp/$defs/withMilliseconds", "title": "Created Timestamp", "description": "The time at which this signature was originally created. The creator can use any time it deems most appropriate as the time the signature was created, but it MUST be precise to the nearest millisecond (exactly three digits after the decimal place in seconds). The created property MUST NOT be changed when creating a new version of the signature.", - "$comment": "Normative source: ITU-T X.590 clause 6.3.1", - "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\.[0-9]{3}Z$" + "$comment": "Normative source: ITU-T X.590 clause 6.3.1" }, "modified": { - "$ref": "#/$defs/timestamp", + "$ref": "#/$defs/timestamp/$defs/withMilliseconds", "title": "Modified Timestamp", "description": "The time that this particular version of the signature was last modified. The creator can use any time it deems most appropriate as the time that this version of the signature was modified, but it MUST be precise to the nearest millisecond (exactly three digits after the decimal place in seconds). The modified property MUST be later than or equal to the value of the created property. If the created and modified properties are the same, then this is the first version of the signature.", - "$comment": "Normative source: ITU-T X.590 clause 6.3.1. Cross-field invariant: 'modified' MUST be greater than or equal to 'created'. JSON Schema 2020-12 cannot compare two sibling property values, so this constraint is NOT enforced by this schema and MUST be validated by the consuming tool or conformance suite.", - "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\.[0-9]{3}Z$" + "$comment": "Normative source: ITU-T X.590 clause 6.3.1. Cross-field invariant: 'modified' MUST be greater than or equal to 'created'. JSON Schema 2020-12 cannot compare two sibling property values, so this constraint is NOT enforced by this schema and MUST be validated by the consuming tool or conformance suite." }, "revoked": { "title": "Revoked Flag", @@ -234,18 +245,22 @@ "required": ["hash_algorithm", "algorithm", "value"], "anyOf": [ { + "properties": { "public_key": true }, "required": ["public_key"], "description": "Public key material provided as PEM-encoded public key (header/footer stripped)." }, { + "properties": { "public_cert_chain": true }, "required": ["public_cert_chain"], "description": "Public key material provided as a base64-encoded DER X.509 certificate chain." }, { + "properties": { "cert_url": true }, "required": ["cert_url"], "description": "Public key material provided by reference to a TLS-accessible certificate URI." }, { + "properties": { "thumbprint": true }, "required": ["thumbprint"], "description": "Public key material referenced by a base64URL-encoded SHA-256 certificate thumbprint." } diff --git a/schema/2.0/model/cyclonedx-license-2.0.schema.json b/schema/2.0/model/cyclonedx-license-2.0.schema.json index 04266739e..2faa5543a 100644 --- a/schema/2.0/model/cyclonedx-license-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-license-2.0.schema.json @@ -111,9 +111,11 @@ "description": "Specifies the details and attributes related to a software license. It can either include a valid SPDX license identifier or a named license, along with additional properties such as license acknowledgment, comprehensive commercial licensing information, and the full text of the license.", "oneOf": [ { + "properties": { "id": true }, "required": ["id"] }, { + "properties": { "name": true }, "required": ["name"] } ], @@ -203,9 +205,11 @@ }, "oneOf":[ { + "properties": { "organization": true }, "required": ["organization"] }, { + "properties": { "individual": true }, "required": ["individual"] } ] @@ -229,9 +233,11 @@ }, "oneOf":[ { + "properties": { "organization": true }, "required": ["organization"] }, { + "properties": { "individual": true }, "required": ["individual"] } ] @@ -255,9 +261,11 @@ }, "oneOf":[ { + "properties": { "organization": true }, "required": ["organization"] }, { + "properties": { "individual": true }, "required": ["individual"] } ] diff --git a/schema/2.0/model/cyclonedx-metadata-2.0.schema.json b/schema/2.0/model/cyclonedx-metadata-2.0.schema.json index 1ddcd24e7..5da767611 100644 --- a/schema/2.0/model/cyclonedx-metadata-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-metadata-2.0.schema.json @@ -69,6 +69,7 @@ "title": "Distribution Constraints", "description": "Conditions and constraints governing the sharing and distribution of the data or components described by this BOM.", "type": "object", + "additionalProperties": false, "properties": { "tlp": { "$ref": "#/$defs/tlpClassification", diff --git a/schema/2.0/model/cyclonedx-party-2.0.schema.json b/schema/2.0/model/cyclonedx-party-2.0.schema.json index a0d41369c..80eac956b 100644 --- a/schema/2.0/model/cyclonedx-party-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-party-2.0.schema.json @@ -51,10 +51,22 @@ "externalReferences": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" } }, "oneOf": [ - { "required": [ "organization" ] }, - { "required": [ "person" ] }, - { "required": [ "system" ] }, - { "required": [ "persona" ] } + { + "properties": { "organization": true }, + "required": [ "organization" ] + }, + { + "properties": { "person": true }, + "required": [ "person" ] + }, + { + "properties": { "system": true }, + "required": [ "system" ] + }, + { + "properties": { "persona": true }, + "required": [ "persona" ] + } ] }, "parties": { diff --git a/schema/2.0/model/cyclonedx-patent-2.0.schema.json b/schema/2.0/model/cyclonedx-patent-2.0.schema.json index 2ab161fa2..b66d9c783 100644 --- a/schema/2.0/model/cyclonedx-patent-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-patent-2.0.schema.json @@ -216,7 +216,7 @@ "title": "Patent References", "description": "A list of BOM references (`bom-ref`) linking to patents or patent families associated with this assertion.", "items": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType" + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" } }, "asserter": { diff --git a/schema/2.0/model/cyclonedx-physical-2.0.schema.json b/schema/2.0/model/cyclonedx-physical-2.0.schema.json index 1dc548234..a93931842 100644 --- a/schema/2.0/model/cyclonedx-physical-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-physical-2.0.schema.json @@ -271,8 +271,8 @@ "title": "Range", "description": "Observed range of lead times, useful when supply is volatile.", "anyOf": [ - { "required": ["min"] }, - { "required": ["max"] } + { "required": ["min"], "properties": { "min": true } }, + { "required": ["max"], "properties": { "max": true } } ], "additionalProperties": false, "properties": { diff --git a/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json b/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json index eba0dafba..2c5245866 100644 --- a/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json @@ -102,6 +102,7 @@ "type": "object", "title": "Proof of Concept", "description": "Evidence used to reproduce the vulnerability.", + "additionalProperties": false, "properties": { "reproductionSteps": { "type": "string", @@ -291,9 +292,11 @@ "type": "object", "oneOf": [ { + "properties": { "version": true }, "required": ["version"] }, { + "properties": { "range": true }, "required": ["range"] } ], @@ -653,6 +656,7 @@ "required": [ "methods" ], "properties": { "methods": { + "type": "array", "minItems": 1, "contains": { "required": [ "technique" ], @@ -669,7 +673,10 @@ "result": { "not": { "enum": [ "not-detected", "inconclusive" ] } } - } + }, + "additionalProperties": true, + "$comment": "additionalProperties explicitly allowed - this is just a minimal constraint", + "type": "object" } } } diff --git a/tools/src/test/js/schema-v2/json-schema-semantic-tests.js b/tools/src/test/js/schema-v2/json-schema-semantic-tests.js index c295f4859..cc8dae2df 100644 --- a/tools/src/test/js/schema-v2/json-schema-semantic-tests.js +++ b/tools/src/test/js/schema-v2/json-schema-semantic-tests.js @@ -211,7 +211,8 @@ function testRefTypeUsage(schema, schemaFile) { } continue } - if (ref === refTypeRef && path !== exceptionPath) { + if (ref === refTypeRef) { + if (exceptionPath && path.startsWith(exceptionPath)) continue; ++errCnt _printError( ref, `different from: ${refTypeRef}`, @@ -223,24 +224,54 @@ function testRefTypeUsage(schema, schemaFile) { } /** - * object schemas must have `additionalProperties: false`, - * unless explicitly allowed via `$comment`. + * object schemas must have `additionalProperties` set, + * unless `unevaluatedProperties` is set, + * or `$comment` containing 'this is a mixin', + * or explicitly allowed via `$comment` containing 'additionalproperties explicitly allowed'. * @param {*} schema * @param {string} schemaFile * @return {number} number of errors found */ -function testAdditionalPropertiesFalse(schema, schemaFile) { +function testAdditionalProperties(schema, schemaFile) { let errCnt = 0 for (const [path, node] of _findObjectSchemas(schema)) { - if (path.endsWith('.if') || path.endsWith('.not')) continue; - const expected = typeof node['$comment'] === 'string' - && node['$comment'].includes('additionalProperties explicitly allowed') - const actual = node['additionalProperties'] + if (Object.keys(node).join('|') === 'type') { + // this is a sole type constraint + continue + } + + const unevaluatedProperties = node.unevaluatedProperties + const additionalProperties = node.additionalProperties + + if (unevaluatedProperties !== undefined) { + // Don't need 'additionalProperties', since 'unevaluatedProperties' takes care. + // see https://json-schema.org/draft/2020-12/json-schema-core#section-11.3 + if (additionalProperties !== undefined) { + ++errCnt + _printError( + 'both set', 'exactly one set', + 'either .additionalProperties or .unevaluatedProperties should be set', + schemaFile, path) + } + continue; + } + + const commentLC = typeof node['$comment'] === 'string' + ? node['$comment'].toLowerCase() + : '' + + if (commentLC.includes('this is a mixin')) { + // This is a mixin. It intentionally does NOT restrict additional/unevaluated properties itself; schemas composing it via `allOf` are expected to close themselves with `unevaluatedProperties: false` so that both their own defined properties and these patternProperties remain usable. + continue; + } + + const expected = commentLC.includes('additionalproperties explicitly allowed') + const actual = additionalProperties if (actual !== expected) { ++errCnt _printError( actual, expected, - 'wrong .additionalProperties', + 'either .additionalProperties or .unevaluatedProperties must be set', schemaFile, path) } } @@ -300,7 +331,7 @@ function testMetaEnum(schema, schemaFile) { const tests = Object.freeze({ 'no self-$ref by file': testNoSelfRefByFile, 'refType usage (`bom-ref` <-> refType)': testRefTypeUsage, - 'additionalProperties is `false`': testAdditionalPropertiesFalse, + 'additionalProperties is `false`': testAdditionalProperties, 'meta:enum completeness': testMetaEnum, }) @@ -325,4 +356,4 @@ console.log('\n\n> found', errCnt, 'errors') // The status 0 is used to terminate the program successfully. process.exitCode = Math.min(errCnt, 254) -// endregion main \ No newline at end of file +// endregion main diff --git a/tools/src/test/resources/2.0/invalid-component-choice-missing-name-2.0.json b/tools/src/test/resources/2.0/invalid-component-choice-missing-name-2.0.json deleted file mode 100644 index 0a47f56a9..000000000 --- a/tools/src/test/resources/2.0/invalid-component-choice-missing-name-2.0.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", - "specFormat": "CycloneDX", - "specVersion": "2.0", - "version": 1, - "metadata": { - "component": { - "type": "device", - "name": "Acme Product" - } - }, - "components": [ - { - "type": "component-choice", - "operator": "XOR", - "components": [ - { "type": "device", "name": "Transistor A" }, - { "type": "device", "name": "Transistor B" } - ] - } - ] -} diff --git a/tools/src/test/resources/2.0/invalid-extensible-properties-array-item-nested-object-missing-schema.json b/tools/src/test/resources/2.0/invalid-extensible-properties-array-item-nested-object-missing-schema.json new file mode 100644 index 000000000..703e5793d --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-extensible-properties-array-item-nested-object-missing-schema.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0" + } + ], + "ext:tools.example.io:array-item-nested-object-missing-schema": [[ + { + } + ]] +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/invalid-extensible-properties-array-item-object-missing-schema.json b/tools/src/test/resources/2.0/invalid-extensible-properties-array-item-object-missing-schema.json new file mode 100644 index 000000000..6da0d22fe --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-extensible-properties-array-item-object-missing-schema.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0" + } + ], + "ext:tools.example.io:array-item-object-missing-schema": [ + { + } + ] +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/invalid-extensible-properties-item-wrong-prefix.json b/tools/src/test/resources/2.0/invalid-extensible-properties-item-wrong-prefix.json new file mode 100644 index 000000000..0282f69bb --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-extensible-properties-item-wrong-prefix.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0" + } + ], + "example.com:booleanValue": "not `ext:: - missing prefix", + "ext:example:stringValue": "not `ext:: - missing TLD", + "ext:example.com:": "not `ext:: - missing name" +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/invalid-extensible-properties-object-missing-schema.json b/tools/src/test/resources/2.0/invalid-extensible-properties-object-missing-schema.json new file mode 100644 index 000000000..06911da67 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-extensible-properties-object-missing-schema.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0" + } + ], + "ext:example.org:object-missing-schema": { + } +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-attestation-2.0.json b/tools/src/test/resources/2.0/valid-attestation-2.0.json index 9d3273d76..9adb90181 100644 --- a/tools/src/test/resources/2.0/valid-attestation-2.0.json +++ b/tools/src/test/resources/2.0/valid-attestation-2.0.json @@ -34,14 +34,17 @@ } } ], - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" + ], + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" + } + ] } ], "claims": [ @@ -59,14 +62,17 @@ "url": "https://alm.example.com" } ], - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" + ], + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" + } + ] } ], "evidence": [ @@ -83,26 +89,29 @@ "mediaType": "text/plain" } }, - "classification": "PII", + "classification": "classified", "sensitiveData": ["Describe sensitive data here"] } ], - "created": "2023-04-25T00:00:00+00:00", - "expires": "2023-05-25T00:00:00+00:00", + "created": "2023-04-25T00:00:00Z", + "expires": "2023-05-25T00:00:00Z", "author": { "name": "Mary" }, "reviewer": { "name": "Jane" }, - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" + ], + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" + } + ] }, { "bom-ref": "counterEvidence-1", @@ -117,26 +126,29 @@ "mediaType": "text/plain" } }, - "classification": "Public", + "classification": "public", "sensitiveData": ["Describe sensitive data here"] } ], - "created": "2023-04-25T00:00:00+00:00", - "expires": "2023-05-25T00:00:00+00:00", + "created": "2023-04-25T00:00:00Z", + "expires": "2023-05-25T00:00:00Z", "author": { "name": "Mary" }, "reviewer": { "name": "Jane" }, - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" + ], + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" + } + ] }, { "bom-ref": "mitigationStrategy-1", @@ -151,26 +163,29 @@ "mediaType": "text/plain" } }, - "classification": "Company Confidential", + "classification": "internal", "sensitiveData": ["Describe sensitive data here"] } ], - "created": "2023-04-25T00:00:00+00:00", - "expires": "2023-05-25T00:00:00+00:00", + "created": "2023-04-25T00:00:00Z", + "expires": "2023-05-25T00:00:00Z", "author": { "name": "Mary" }, "reviewer": { "name": "Jane" }, - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" + ], + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" + } + ] } ], "targets": { @@ -187,14 +202,17 @@ { "name": "Tom", "role": "CEO", - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" + ], + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" + } + ] }, { "name": "Jerry", @@ -208,30 +226,39 @@ } } ], - "signature": { + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" + ], + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" + } + ] + }, + "signatures": [ + { + "hash_algorithm": "sha-256", "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" ], - "value": "tqIT..." + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" } - }, - "signature": { + ] + }, + "signatures": [ + { + "hash_algorithm": "sha-256", "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." + "public_cert_chain": [ + "MIIBpjCCAUygAwIBAgIUJlq9zImYoVdcurFZwr37H3aCsWowCgYIKoZIzj0EAwIw", + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG" ], - "value": "tqIT..." + "value": "tqITqhKnwt4vQcRWjc1UbRp_ds2AeYNPeXCEQFXZfPGmMEW4c1JJmPRnRhFPQ8Vc" } - }, - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + ] } diff --git a/tools/src/test/resources/2.0/valid-bom-2.0.json b/tools/src/test/resources/2.0/valid-bom-2.0.json index 1c6d96f34..af4ffa09a 100644 --- a/tools/src/test/resources/2.0/valid-bom-2.0.json +++ b/tools/src/test/resources/2.0/valid-bom-2.0.json @@ -10,9 +10,14 @@ "components": [ { "type": "application", - "manufacturer": { - "name": "Awesome Vendor" - }, + "parties": [ + { + "roles": [ { "role": "manufacturer" } ], + "organization": { + "name": "Awesome Vendor" + } + } + ], "name": "Awesome Tool", "version": "9.1.2", "hashes": [ @@ -37,7 +42,12 @@ ], "component": { "type": "application", - "authors": [ { "name": "Acme Super Heroes" } ], + "parties": [ + { + "roles": [ { "role": "author" } ], + "organization": { "name": "Acme Super Heroes" } + } + ], "name": "Acme Application", "version": "9.1.1", "identifiers": [ @@ -82,8 +92,16 @@ { "bom-ref": "pkg:maven/com.acme/acme-catalina@9.0.14?packaging=jar", "type": "application", - "authors": [ { "name": "Joane Doe et al." } ], - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "author" } ], + "person": { "name": "Joane Doe et al." } + }, + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "acme-catalina", "version": "9.0.14", @@ -130,8 +148,16 @@ "ancestors": [ { "type": "application", - "authors": [ { "name": "Globex Super Heroes" } ], - "publisher": "Globex", + "parties": [ + { + "roles": [ { "role": "author" } ], + "person": { "name": "Globex Super Heroes" } + }, + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Globex" } + } + ], "group": "org.globex.catalina", "name": "globex-catalina", "version": "9.0.14", @@ -179,45 +205,56 @@ { "type": "library", "bom-ref": "pkg:maven/com.example/myapplication@1.0.0?packaging=war", - "supplier": { - "name": "Example, Inc.", - "url": [ - "https://example.com", - "https://example.net" - ], - "contact": [ - { + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { + "name": "Example, Inc.", + "url": [ + { "name": "homepage", "url": "https://example.com" }, + { "name": "homepage", "url": "https://example.net" } + ] + } + }, + { + "roles": [ { "role": "support-contact" } ], + "person": { "name": "Example Support AMER", - "email": "support@example.com", - "phone": "800-555-1212" - }, - { + "email": [ { "address": "support@example.com" } ], + "phone": [ { "number": "800-555-1212" } ] + } + }, + { + "roles": [ { "role": "support-contact" } ], + "person": { "name": "Example Support APAC", - "email": "support@apac.example.com" + "email": [ { "address": "support@apac.example.com" } ] } - ] - }, - "manufacturer": { - "bom-ref": "example-2-inc", - "name": "Example-2, Inc.", - "url": [ - "https://example.org" - ], - "contact": [ - { - "email": "support@example.org" + }, + { + "bom-ref": "example-2-inc", + "roles": [ { "role": "manufacturer" } ], + "organization": { + "name": "Example-2, Inc.", + "url": [ + { "name": "homepage", "url": "https://example.org" } + ] } - ] - }, - "authors": [ + }, { - "name": "Anthony Edward Stark", - "phone": "555-212-970-4133", - "email": "ironman@example.org" + "roles": [ { "role": "author" } ], + "person": { + "name": "Anthony Edward Stark", + "phone": [ { "number": "555-212-970-4133" } ], + "email": [ { "address": "ironman@example.org" } ] + } }, { - "name": "Peter Benjamin Parker", - "email": "spiderman@example.org" + "roles": [ { "role": "author" } ], + "person": { + "name": "Peter Benjamin Parker", + "email": [ { "address": "spiderman@example.org" } ] + } } ], "group": "org.example", @@ -277,9 +314,10 @@ }, { "type": "framework", - "authors": [ + "parties": [ { - "name": "Example Super Heroes" + "roles": [ { "role": "author" } ], + "organization": { "name": "Example Super Heroes" } } ], "group": "com.example", @@ -343,4 +381,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-component-choice-and-2.0.json b/tools/src/test/resources/2.0/valid-component-choice-and-2.0.json index 6a3edfb59..b9fe50ea2 100644 --- a/tools/src/test/resources/2.0/valid-component-choice-and-2.0.json +++ b/tools/src/test/resources/2.0/valid-component-choice-and-2.0.json @@ -20,14 +20,24 @@ { "type": "device", "name": "2.4GHz RF Transceiver", - "supplier": { "name": "Acme RF" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Acme RF" } + } + ] }, { "type": "device", "name": "Matching Balun for 2.4GHz Transceiver", - "supplier": { "name": "Acme RF" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Acme RF" } + } + ] } ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-component-choice-in-nested-components-2.0.json b/tools/src/test/resources/2.0/valid-component-choice-in-nested-components-2.0.json index a52a39388..af1d43739 100644 --- a/tools/src/test/resources/2.0/valid-component-choice-in-nested-components-2.0.json +++ b/tools/src/test/resources/2.0/valid-component-choice-in-nested-components-2.0.json @@ -27,16 +27,26 @@ { "type": "device", "name": "LD1117S50TR", - "supplier": { "name": "STMicroelectronics" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "STMicroelectronics" } + } + ] }, { "type": "device", "name": "AMS1117-5.0", - "supplier": { "name": "Advanced Monolithic Systems" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Advanced Monolithic Systems" } + } + ] } ] } ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-component-choice-nested-2.0.json b/tools/src/test/resources/2.0/valid-component-choice-nested-2.0.json index f91fa1e68..344eae8ca 100644 --- a/tools/src/test/resources/2.0/valid-component-choice-nested-2.0.json +++ b/tools/src/test/resources/2.0/valid-component-choice-nested-2.0.json @@ -25,12 +25,22 @@ { "type": "device", "name": "2.4GHz Transceiver", - "supplier": { "name": "Acme RF" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Acme RF" } + } + ] }, { "type": "device", "name": "2.4GHz Balun", - "supplier": { "name": "Acme RF" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Acme RF" } + } + ] } ] }, @@ -42,16 +52,26 @@ { "type": "device", "name": "915MHz Transceiver", - "supplier": { "name": "Beta RF" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Beta RF" } + } + ] }, { "type": "device", "name": "915MHz Balun", - "supplier": { "name": "Beta RF" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Beta RF" } + } + ] } ] } ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-component-choice-or-2.0.json b/tools/src/test/resources/2.0/valid-component-choice-or-2.0.json index 700fbe354..c4f649981 100644 --- a/tools/src/test/resources/2.0/valid-component-choice-or-2.0.json +++ b/tools/src/test/resources/2.0/valid-component-choice-or-2.0.json @@ -21,19 +21,34 @@ { "type": "device", "name": "Ceramic Capacitor 0.1uF 0805 X7R", - "supplier": { "name": "Kemet" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Kemet" } + } + ] }, { "type": "device", "name": "Ceramic Capacitor 0.1uF 0805 X7R", - "supplier": { "name": "TDK" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "TDK" } + } + ] }, { "type": "device", "name": "Ceramic Capacitor 0.1uF 0805 X7R", - "supplier": { "name": "Murata" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Murata" } + } + ] } ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-component-choice-xor-2.0.json b/tools/src/test/resources/2.0/valid-component-choice-xor-2.0.json index 48309767e..314d6a144 100644 --- a/tools/src/test/resources/2.0/valid-component-choice-xor-2.0.json +++ b/tools/src/test/resources/2.0/valid-component-choice-xor-2.0.json @@ -25,19 +25,34 @@ { "type": "device", "name": "NPN Transistor 2N2222", - "supplier": { "name": "Company A" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Company A" } + } + ] }, { "type": "device", "name": "NPN Transistor 2N2222", - "supplier": { "name": "Company B" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Company B" } + } + ] }, { "type": "device", "name": "NPN Transistor PN2222A", - "supplier": { "name": "Company C" } + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Company C" } + } + ] } ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-component-swid-2.0.json b/tools/src/test/resources/2.0/valid-component-swid-2.0.json index 8bdca8961..31539197d 100644 --- a/tools/src/test/resources/2.0/valid-component-swid-2.0.json +++ b/tools/src/test/resources/2.0/valid-component-swid-2.0.json @@ -13,9 +13,10 @@ "components": [ { "type": "application", - "authors": [ + "parties": [ { - "name": "Acme Super Heroes" + "roles": [ { "role": "author" } ], + "organization": { "name": "Acme Super Heroes" } } ], "name": "Acme Application", @@ -33,4 +34,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-component-swid-full-2.0.json b/tools/src/test/resources/2.0/valid-component-swid-full-2.0.json index 50d1c600c..1fa56ab07 100644 --- a/tools/src/test/resources/2.0/valid-component-swid-full-2.0.json +++ b/tools/src/test/resources/2.0/valid-component-swid-full-2.0.json @@ -13,9 +13,10 @@ "components": [ { "type": "application", - "authors": [ + "parties": [ { - "name": "Acme Super Heroes" + "roles": [ { "role": "author" } ], + "organization": { "name": "Acme Super Heroes" } } ], "name": "Acme Application", @@ -40,4 +41,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-cryptography-certificate-2.0.json b/tools/src/test/resources/2.0/valid-cryptography-certificate-2.0.json index 71b3ec8c5..46bf40f8e 100644 --- a/tools/src/test/resources/2.0/valid-cryptography-certificate-2.0.json +++ b/tools/src/test/resources/2.0/valid-cryptography-certificate-2.0.json @@ -42,7 +42,7 @@ "relatedCryptographicAssets": [ { "type": "algorithm", - "ref": "6b00f384-6c39-420f-91eb-94de0f7be569RR" + "ref": "6b00f384-6c39-420f-91eb-94de0f7be569" }, { "type": "publicKey", @@ -62,7 +62,9 @@ "algorithmProperties": { "primitive": "signature", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ + "x86_64" + ], "certificationLevel": [ "none" ], @@ -120,7 +122,9 @@ "algorithmFamily": "RSAES-OAEP", "parameterSetIdentifier": "2048", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ + "x86_64" + ], "certificationLevel": [ "none" ], @@ -167,6 +171,105 @@ }, "oid": "1.3.6.1.5.5.7.3.1" } + }, + { + "name": "AES-256-GCM", + "type": "cryptographic-asset", + "bom-ref": "1977d71b-8981-4292-b40d-842a019c2229", + "cryptoProperties": { + "assetType": "algorithm", + "algorithmProperties": { + "primitive": "ae", + "algorithmFamily": "AES", + "parameterSetIdentifier": "256", + "mode": "gcm", + "executionEnvironment": "software-plain-ram", + "implementationPlatform": [ + "x86_64" + ], + "certificationLevel": [ + "none" + ], + "cryptoFunctions": [ + "encrypt", + "decrypt" + ] + }, + "oid": "2.16.840.1.101.3.4.1.46" + } + }, + { + "name": "SHA-384", + "type": "cryptographic-asset", + "bom-ref": "422fa336-b401-42b7-89b8-8966aa30bca0", + "cryptoProperties": { + "assetType": "algorithm", + "algorithmProperties": { + "primitive": "hash", + "algorithmFamily": "SHA-2", + "parameterSetIdentifier": "384", + "executionEnvironment": "software-plain-ram", + "implementationPlatform": [ + "x86_64" + ], + "certificationLevel": [ + "none" + ], + "cryptoFunctions": [ + "digest" + ] + }, + "oid": "2.16.840.1.101.3.4.2.2" + } + }, + { + "name": "ChaCha20-Poly1305", + "type": "cryptographic-asset", + "bom-ref": "1af4fc08-5d0d-436e-8058-eeef921983d0", + "cryptoProperties": { + "assetType": "algorithm", + "algorithmProperties": { + "primitive": "ae", + "algorithmFamily": "ChaCha20", + "parameterSetIdentifier": "256", + "executionEnvironment": "software-plain-ram", + "implementationPlatform": [ + "x86_64" + ], + "certificationLevel": [ + "none" + ], + "cryptoFunctions": [ + "encrypt", + "decrypt" + ] + }, + "oid": "1.2.840.113549.1.9.16.3.18" + } + }, + { + "name": "SHA-256", + "type": "cryptographic-asset", + "bom-ref": "6af3066b-ab66-4593-975f-d9ba2c623a89", + "cryptoProperties": { + "assetType": "algorithm", + "algorithmProperties": { + "primitive": "hash", + "algorithmFamily": "SHA-2", + "parameterSetIdentifier": "256", + "executionEnvironment": "software-plain-ram", + "implementationPlatform": [ + "x86_64" + ], + "certificationLevel": [ + "none" + ], + "cryptoFunctions": [ + "digest" + ] + }, + "oid": "2.16.840.1.101.3.4.2.1" + } } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-cryptography-certificate-advanced-2.0.json b/tools/src/test/resources/2.0/valid-cryptography-certificate-advanced-2.0.json index 1ac4dbeed..1c7ab2245 100644 --- a/tools/src/test/resources/2.0/valid-cryptography-certificate-advanced-2.0.json +++ b/tools/src/test/resources/2.0/valid-cryptography-certificate-advanced-2.0.json @@ -183,7 +183,9 @@ "algorithmProperties": { "primitive": "signature", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ + "x86_64" + ], "padding": "pkcs1v15", "cryptoFunctions": [ "sign", @@ -203,7 +205,9 @@ "primitive": "signature", "ellipticCurve": "secg/secp256r1", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ + "x86_64" + ], "certificationLevel": ["fips140-3-l1"], "cryptoFunctions": [ "sign", @@ -213,6 +217,29 @@ "oid": "1.2.840.10045.4.3.2" } }, + { + "name": "AES-256-GCM", + "type": "cryptographic-asset", + "bom-ref": "aes-256-gcm-ref", + "cryptoProperties": { + "assetType": "algorithm", + "algorithmProperties": { + "primitive": "ae", + "algorithmFamily": "AES", + "parameterSetIdentifier": "256", + "mode": "gcm", + "executionEnvironment": "hardware", + "implementationPlatform": [ + "x86_64" + ], + "cryptoFunctions": [ + "encrypt", + "decrypt" + ] + }, + "oid": "2.16.840.1.101.3.4.1.46" + } + }, { "name": "RSA-4096-Revoked-CA-Key", "type": "cryptographic-asset", @@ -231,7 +258,9 @@ "updateDate": "2024-01-10T15:45:30Z", "securedBy": { "mechanism": "HSM", - "algorithmRef": "aes-256-gcm-ref" + "algorithmRef": [ + "aes-256-gcm-ref" + ] }, "fingerprint": { "alg": "SHA-256", @@ -265,7 +294,9 @@ "expirationDate": "2025-01-01T23:59:59Z", "securedBy": { "mechanism": "HSM", - "algorithmRef": "aes-256-gcm-ref" + "algorithmRef": [ + "aes-256-gcm-ref" + ] }, "fingerprint": { "alg": "SHA-256", @@ -282,4 +313,4 @@ } } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-cryptography-full-2.0.json b/tools/src/test/resources/2.0/valid-cryptography-full-2.0.json index edb1a40b6..66a96853b 100644 --- a/tools/src/test/resources/2.0/valid-cryptography-full-2.0.json +++ b/tools/src/test/resources/2.0/valid-cryptography-full-2.0.json @@ -17,7 +17,7 @@ "parameterSetIdentifier": "160", "ellipticCurve": "brainpool/brainpoolP160r1", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l4"], "cryptoFunctions": [ "keygen", @@ -40,7 +40,7 @@ "algorithmFamily": "RSASSA-PKCS1", "parameterSetIdentifier": "2048", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "padding": "pkcs1v15", "cryptoFunctions": ["sign", "verify"], @@ -61,7 +61,7 @@ "parameterSetIdentifier": "256", "mode": "gcm", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "cryptoFunctions": ["keygen", "encrypt", "decrypt", "tag"], "classicalSecurityLevel": 256, @@ -81,7 +81,7 @@ "algorithmFamily": "SHA-2", "parameterSetIdentifier": "256", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "cryptoFunctions": ["digest"] }, @@ -99,7 +99,7 @@ "algorithmFamily": "SHA-2", "parameterSetIdentifier": "384", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "cryptoFunctions": ["digest"] }, @@ -118,7 +118,7 @@ "parameterSetIdentifier": "128", "mode": "gcm", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "cryptoFunctions": ["keygen", "encrypt", "decrypt", "tag"], "classicalSecurityLevel": 128, @@ -137,7 +137,7 @@ "primitive": "ae", "algorithmFamily": "ChaCha20", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["none"], "cryptoFunctions": ["keygen", "encrypt", "decrypt", "tag"], "classicalSecurityLevel": 256, @@ -156,7 +156,7 @@ "primitive": "key-agree", "algorithmFamily": "FFDH", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "cryptoFunctions": ["keygen", "keyderive"] }, @@ -174,7 +174,7 @@ "algorithmFamily": "ECDSA", "ellipticCurve": "secg/secp256r1", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "cryptoFunctions": ["sign", "verify"] }, @@ -192,7 +192,7 @@ "algorithmFamily": "RSAES-OAEP", "parameterSetIdentifier": "4096", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["fips140-3-l1"], "padding": "oaep", "cryptoFunctions": ["keygen", "encrypt", "decrypt"] @@ -219,7 +219,7 @@ "format": "PEM", "securedBy": { "mechanism": "HSM", - "algorithmRef": "algorithm-aes-256-gcm" + "algorithmRef": [ "algorithm-aes-256-gcm" ] }, "fingerprint": { "alg": "SHA-256", diff --git a/tools/src/test/resources/2.0/valid-cryptography-implementation-2.0.json b/tools/src/test/resources/2.0/valid-cryptography-implementation-2.0.json index 8a5df3649..764308eec 100644 --- a/tools/src/test/resources/2.0/valid-cryptography-implementation-2.0.json +++ b/tools/src/test/resources/2.0/valid-cryptography-implementation-2.0.json @@ -24,7 +24,7 @@ "parameterSetIdentifier": "128", "mode": "gcm", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["none"], "cryptoFunctions": [ "keygen", @@ -48,7 +48,7 @@ "primitive": "signature", "parameterSetIdentifier": "512", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["none"], "cryptoFunctions": [ "sign", @@ -70,7 +70,7 @@ "ellipticCurve": "secg/secp521r1", "primitive": "key-agree", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["none"], "cryptoFunctions": [ "keygen", @@ -91,7 +91,7 @@ "algorithmFamily": "ML-KEM", "primitive": "kem", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["none"], "cryptoFunctions": [ "keygen", @@ -111,7 +111,7 @@ "algorithmProperties": { "primitive": "combiner", "executionEnvironment": "software-plain-ram", - "implementationPlatform": "x86_64", + "implementationPlatform": [ "x86_64" ], "certificationLevel": ["none"], "cryptoFunctions": [ "keygen", @@ -132,4 +132,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-evidence-2.0.json b/tools/src/test/resources/2.0/valid-evidence-2.0.json index c78ba942b..c284a6166 100644 --- a/tools/src/test/resources/2.0/valid-evidence-2.0.json +++ b/tools/src/test/resources/2.0/valid-evidence-2.0.json @@ -115,21 +115,56 @@ ], "licenses": [ { - "license": { - "id": "Apache-2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } + "license": { "id": "Apache-2.0" }, + "occurrences": [ + { + "location": "HelloWorld.class", + "line": 8, + "additionalContext": " * http://www.apache.org/licenses/LICENSE-2.0" + } + ] }, { - "license": { - "id": "LGPL-2.1-only", - "url": "https://opensource.org/licenses/LGPL-2.1" - } + "license": { "id": "Apache-2.0" }, + "occurrences": [ + { + "location": "HelloWorld.class", + "line": 16, + "additionalContext": "// SPDX-License-Identifier: Apache-2.0" + } + ] + }, + { + "license": { "id": "MIT" }, + "occurrences": [ + { + "location": "Example.class", + "line": 22, + "additionalContext": "// SPDX-License-Identifier: MIT" + } + ] } ], "copyright": [ { - "text": "Copyright 2012 Acme Inc. All Rights Reserved." + "text": "Copyright 2012 Acme Inc.", + "occurrences": [ + { + "location": "HelloWorld.class", + "line": 2, + "additionalContext": " * Copyright (c) 2012 Acme Inc." + } + ] + }, + { + "text": "Copyright 2011 Example Corporation", + "occurrences": [ + { + "location": "Example.class", + "line": 2, + "additionalContext": " * Copyright (c) 2011 Example Corporation" + } + ] } ] } diff --git a/tools/src/test/resources/2.0/valid-extensible-properties.json b/tools/src/test/resources/2.0/valid-extensible-properties.json new file mode 100644 index 000000000..df94c4054 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-extensible-properties.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0" + } + ], + "ext:example.org:structuredExtension": { + "$schema": "https://example.org/schemas/my-extension.schema.json", + "$comment": "$schema is required", + "customField": "custom value", + "nested": { + "deeply": ["anything", "goes", "here"], + "other-object": { "foo": 42 } + }, + "some-list": ["1", 1, {"one": 1}] + }, + "ext:example.com:stringValue": "a plain string extension", + "ext:example.com:numberValue": 42.5, + "ext:example.com:booleanValue": true, + "ext:example.com:nullValue": null, + "ext:example.com:sub:spaced": "foooo", + "ext:tools.example.io:arrayValue": [ + "item-1", + 23, + { + "$schema": "https://example.org/schemas/my-extension.schema.json", + "$comment": "$schema is required in first appearance of an array item as object", + "customField": "custom value", + "nested": { + "deeply": ["anything", "goes", "here"], + "other-object": { "foo": 42 } + }, + "some-list": ["1", 1, {"one": 1}] + }, + [ + 123, + "nested-1", + { + "$schema": "https://example.org/schemas/my-extension.schema.json", + "$comment": "$schema is required in first appearance of a nested array item as object", + "customField": "custom value", + "nested": { + "deeply": ["anything", "goes", "here"], + "other-object": { "foo": 42 } + }, + "some-list": ["1", 1, {"one": 1}] + } + ] + ] +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-external-reference-2.0.json b/tools/src/test/resources/2.0/valid-external-reference-2.0.json index 95ae5be24..32245c4a0 100644 --- a/tools/src/test/resources/2.0/valid-external-reference-2.0.json +++ b/tools/src/test/resources/2.0/valid-external-reference-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "library", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "org.example", "name": "mylibrary", "version": "1.0.0", @@ -196,6 +201,10 @@ "type": "poam", "url": "http://example.com/extref/poam" }, + { + "type": "perspective", + "url": "http://example.com/extref/perspective" + }, { "type": "electronic-signature", "url": "http://example.com/extref/electronic-signature" @@ -208,6 +217,26 @@ "type": "rfc-9116", "url": "http://example.com/extref/rfc-9116" }, + { + "type": "patent", + "url": "http://example.com/extref/patent" + }, + { + "type": "patent-family", + "url": "http://example.com/extref/patent-family" + }, + { + "type": "patent-assertion", + "url": "http://example.com/extref/patent-assertion" + }, + { + "type": "citation", + "url": "http://example.com/extref/citation" + }, + { + "type": "swid-tag", + "url": "http://example.com/extref/swid-tag" + }, { "type": "other", "url": "http://example.com/extref/other" @@ -215,4 +244,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-formulation-2.0.json b/tools/src/test/resources/2.0/valid-formulation-2.0.json index 1023c8a22..5038abba8 100644 --- a/tools/src/test/resources/2.0/valid-formulation-2.0.json +++ b/tools/src/test/resources/2.0/valid-formulation-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "library", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "org.example", "name": "mylibrary", "version": "1.0.0" @@ -298,4 +303,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-hardware-material-2.0.json b/tools/src/test/resources/2.0/valid-hardware-material-2.0.json index 58fd5e4ea..5caefa351 100644 --- a/tools/src/test/resources/2.0/valid-hardware-material-2.0.json +++ b/tools/src/test/resources/2.0/valid-hardware-material-2.0.json @@ -106,10 +106,15 @@ "value": 2500, "unit": "kg" }, - "supplier": { - "bom-ref": "org-glsm", - "name": "Great Lakes Specialty Metals" - }, + "parties": [ + { + "bom-ref": "org-glsm", + "roles": [ { "role": "supplier" } ], + "organization": { + "name": "Great Lakes Specialty Metals" + } + } + ], "origins": [ { "stage": "mined", diff --git a/tools/src/test/resources/2.0/valid-license-choice-2.0.json b/tools/src/test/resources/2.0/valid-license-choice-2.0.json index c7a6edaf6..6ad3fc51d 100644 --- a/tools/src/test/resources/2.0/valid-license-choice-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-choice-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "application", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", @@ -42,4 +47,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-license-expression-2.0.json b/tools/src/test/resources/2.0/valid-license-expression-2.0.json index 0ca63394e..b31ea348a 100644 --- a/tools/src/test/resources/2.0/valid-license-expression-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-expression-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "application", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", @@ -40,4 +45,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-license-expression-with-licensing-2.0.json b/tools/src/test/resources/2.0/valid-license-expression-with-licensing-2.0.json index f1325e938..151a2a7fa 100644 --- a/tools/src/test/resources/2.0/valid-license-expression-with-licensing-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-expression-with-licensing-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "library", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "cryptographic-provider", "version": "2.2.0", @@ -54,4 +59,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-license-id-2.0.json b/tools/src/test/resources/2.0/valid-license-id-2.0.json index 2f466eb1d..902a3627f 100644 --- a/tools/src/test/resources/2.0/valid-license-id-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-id-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "application", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", @@ -42,4 +47,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-license-id-with-text-2.0.json b/tools/src/test/resources/2.0/valid-license-id-with-text-2.0.json index 30af12fb7..cda103014 100644 --- a/tools/src/test/resources/2.0/valid-license-id-with-text-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-id-with-text-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "application", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", @@ -46,4 +51,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-license-name-2.0.json b/tools/src/test/resources/2.0/valid-license-name-2.0.json index 69c547d49..d6d88d2ce 100644 --- a/tools/src/test/resources/2.0/valid-license-name-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-name-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "application", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", @@ -41,4 +46,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-license-name-with-licensing-2.0.json b/tools/src/test/resources/2.0/valid-license-name-with-licensing-2.0.json index 7749cd3ef..5b2cd8ab9 100644 --- a/tools/src/test/resources/2.0/valid-license-name-with-licensing-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-name-with-licensing-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "library", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "cryptographic-provider", "version": "2.2.0", @@ -54,4 +59,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-license-name-with-text-2.0.json b/tools/src/test/resources/2.0/valid-license-name-with-text-2.0.json index 3525a2b95..0e265dd28 100644 --- a/tools/src/test/resources/2.0/valid-license-name-with-text-2.0.json +++ b/tools/src/test/resources/2.0/valid-license-name-with-text-2.0.json @@ -7,7 +7,12 @@ "components": [ { "type": "application", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", @@ -46,4 +51,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-machine-learning-2.0.json b/tools/src/test/resources/2.0/valid-machine-learning-2.0.json index 7bf6b8f61..c95c7131c 100644 --- a/tools/src/test/resources/2.0/valid-machine-learning-2.0.json +++ b/tools/src/test/resources/2.0/valid-machine-learning-2.0.json @@ -8,7 +8,12 @@ { "bom-ref": "component-a", "type": "machine-learning-model", - "publisher": "Acme Inc", + "parties": [ + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "CompVis", "name": "stable-diffusion", "version": "1.4", @@ -99,4 +104,4 @@ } } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-machine-learning-considerations-env-2.0.json b/tools/src/test/resources/2.0/valid-machine-learning-considerations-env-2.0.json index 3c9009dba..765bcaf5d 100644 --- a/tools/src/test/resources/2.0/valid-machine-learning-considerations-env-2.0.json +++ b/tools/src/test/resources/2.0/valid-machine-learning-considerations-env-2.0.json @@ -10,10 +10,16 @@ "group": "meta-llama", "name": "Llama-2-7b", "type": "machine-learning-model", - "supplier": { - "name": "Hugging Face" - }, - "publisher": "meta", + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Hugging Face" } + }, + { + "roles": [ { "role": "publisher" } ], + "organization": { "name": "meta" } + } + ], "externalReferences": [ { "type": "distribution", @@ -63,4 +69,4 @@ } } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-perspective-2.0.json b/tools/src/test/resources/2.0/valid-perspective-2.0.json index 52f28cecb..382d6590f 100644 --- a/tools/src/test/resources/2.0/valid-perspective-2.0.json +++ b/tools/src/test/resources/2.0/valid-perspective-2.0.json @@ -18,9 +18,12 @@ { "bom-ref": "pkg:maven/com.acme/sample-library@1.0.0?packaging=jar", "type": "library", - "supplier": { - "name": "Acme Inc" - }, + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "sample-library", "version": "1.0.0" @@ -28,9 +31,12 @@ { "bom-ref": "pkg:maven/com.acme/sample-framework@2.1.0?packaging=jar", "type": "library", - "supplier": { - "name": "Acme Inc" - }, + "parties": [ + { + "roles": [ { "role": "supplier" } ], + "organization": { "name": "Acme Inc" } + } + ], "group": "com.acme", "name": "sample-framework", "version": "2.1.0" @@ -102,4 +108,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-standard-2.0.json b/tools/src/test/resources/2.0/valid-standard-2.0.json index 0188ac299..ea31230d0 100644 --- a/tools/src/test/resources/2.0/valid-standard-2.0.json +++ b/tools/src/test/resources/2.0/valid-standard-2.0.json @@ -68,15 +68,18 @@ ] } ], - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB...", - "MIID..." - ], - "value": "tqIT..." - } + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIB...", + "MIID..." + ], + "value": "aa==" + } + ] } ] } -} +} \ No newline at end of file diff --git a/tools/src/test/resources/2.0/valid-vulnerability-evidence-2.0.json b/tools/src/test/resources/2.0/valid-vulnerability-evidence-2.0.json index 1972102fc..2d86a9c66 100644 --- a/tools/src/test/resources/2.0/valid-vulnerability-evidence-2.0.json +++ b/tools/src/test/resources/2.0/valid-vulnerability-evidence-2.0.json @@ -19,14 +19,20 @@ "type": "application", "name": "Acme Binary Analyzer", "version": "2.0.0" - } - ], - "services": [ + }, { "bom-ref": "svc-pentest-platform", - "provider": { - "name": "Acme Inc" - }, + "type": "application", + "parties": [ + { + "roles": [ + { "role": "provider" } + ], + "organization": { + "name": "Acme Inc" + } + } + ], "name": "Acme Penetration Testing Platform" } ] diff --git a/tools/src/test/resources/2.0/valid-vulnerability-evidence-callstacks-2.0.json b/tools/src/test/resources/2.0/valid-vulnerability-evidence-callstacks-2.0.json index 34b3c9173..7bd654fc0 100644 --- a/tools/src/test/resources/2.0/valid-vulnerability-evidence-callstacks-2.0.json +++ b/tools/src/test/resources/2.0/valid-vulnerability-evidence-callstacks-2.0.json @@ -20,8 +20,8 @@ "name": "NVD" }, "description": "The same SQL injection sink is reachable through more than one call path.", - "cwes": [ - 89 + "weaknesses": [ + { "cweId": 89 } ], "analysis": { "state": "exploitable" diff --git a/tools/src/test/resources/2.0/valid-vulnerability-evidence-hardened-2.0.json b/tools/src/test/resources/2.0/valid-vulnerability-evidence-hardened-2.0.json index 50cae33ed..304097ab5 100644 --- a/tools/src/test/resources/2.0/valid-vulnerability-evidence-hardened-2.0.json +++ b/tools/src/test/resources/2.0/valid-vulnerability-evidence-hardened-2.0.json @@ -72,7 +72,7 @@ "sensitiveData": [ "Contains a defanged remote code execution payload." ], - "governance": {}, + "governance": [], "contents": { "url": "https://evidence.example.com/CVE-2024-5678/exploit.txt", "hashes": [ diff --git a/tools/src/test/resources/2.0/valid-vulnerability-evidence-llm-2.0.json b/tools/src/test/resources/2.0/valid-vulnerability-evidence-llm-2.0.json index efcb14192..126a4d732 100644 --- a/tools/src/test/resources/2.0/valid-vulnerability-evidence-llm-2.0.json +++ b/tools/src/test/resources/2.0/valid-vulnerability-evidence-llm-2.0.json @@ -33,8 +33,8 @@ "name": "Acme Security" }, "description": "The assistant is susceptible to indirect prompt injection that overrides its system instructions and exfiltrates conversation context.", - "cwes": [ - 1427 + "weaknesses": [ + { "cweId": 1427 } ], "analysis": { "state": "exploitable" @@ -83,7 +83,7 @@ "content": "Sure. The last user message was: 'my account number is 123456789'." } }, - "classification": "PII" + "classification": "confidential" } ] } diff --git a/tools/src/test/resources/2.0/valid-vulnerability-evidence-sast-rule-2.0.json b/tools/src/test/resources/2.0/valid-vulnerability-evidence-sast-rule-2.0.json index 60d34a98f..fb92650ff 100644 --- a/tools/src/test/resources/2.0/valid-vulnerability-evidence-sast-rule-2.0.json +++ b/tools/src/test/resources/2.0/valid-vulnerability-evidence-sast-rule-2.0.json @@ -45,8 +45,8 @@ "name": "Acme Security" }, "description": "SQL injection in a custom data access path, identified in first-party code and not tracked as a CVE.", - "cwes": [ - 89 + "weaknesses": [ + { "cweId": 89 } ], "analysis": { "state": "exploitable"