From 81479889778cd0538189f84bbcfab6e50f175d69 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Sun, 1 Mar 2026 14:35:52 -0600 Subject: [PATCH] Migrated enveloped signature support from JSF to JSS. Expanded on the number of valid and invalid use cases. Signed-off-by: Steve Springett --- schema/2.0/cyclonedx-2.0.schema.json | 4 +- .../cyclonedx-annotation-2.0.schema.json | 4 +- .../model/cyclonedx-citation-2.0.schema.json | 4 +- .../model/cyclonedx-common-2.0.schema.json | 8 +- .../model/cyclonedx-component-2.0.schema.json | 4 +- .../cyclonedx-composition-2.0.schema.json | 4 +- .../cyclonedx-declaration-2.0.schema.json | 24 +- ...cyclonedx-jss_X590_2023_10-2.0.schema.json | 259 ++++++++++++++++++ .../model/cyclonedx-service-2.0.schema.json | 4 +- .../model/cyclonedx-standard-2.0.schema.json | 4 +- ...d-jss-signature-created-no-millis-2.0.json | 23 ++ ...id-jss-signature-empty-cert-chain-2.0.json | 22 ++ ...id-jss-signature-empty-signatures-2.0.json | 15 + ...d-jss-signature-invalid-timestamp-2.0.json | 23 ++ ...d-jss-signature-missing-algorithm-2.0.json | 21 ++ ...-signature-missing-hash-algorithm-2.0.json | 21 ++ ...valid-jss-signature-missing-value-2.0.json | 21 ++ ...-jss-signature-modified-no-millis-2.0.json | 23 ++ ...lid-jss-signature-no-key-material-2.0.json | 21 ++ ...nvalid-jss-signature-type-not-jss-2.0.json | 23 ++ .../2.0/valid-jss-signature-cert-url-2.0.json | 22 ++ ...d-jss-signature-counter-signature-2.0.json | 28 ++ ...d-jss-signature-custom-properties-2.0.json | 24 ++ .../2.0/valid-jss-signature-metadata-2.0.json | 32 +++ .../2.0/valid-jss-signature-multiple-2.0.json | 28 ++ ...d-jss-signature-public-cert-chain-2.0.json | 24 ++ .../valid-jss-signature-public-key-2.0.json | 22 ++ .../valid-jss-signature-thumbprint-2.0.json | 22 ++ .../resources/2.0/valid-signatures-2.0.json | 79 ------ 29 files changed, 704 insertions(+), 109 deletions(-) create mode 100644 schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-created-no-millis-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-empty-cert-chain-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-empty-signatures-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-invalid-timestamp-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-missing-algorithm-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-missing-hash-algorithm-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-missing-value-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-modified-no-millis-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-no-key-material-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-jss-signature-type-not-jss-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-cert-url-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-counter-signature-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-custom-properties-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-metadata-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-multiple-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-public-cert-chain-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-public-key-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-jss-signature-thumbprint-2.0.json delete mode 100644 tools/src/test/resources/2.0/valid-signatures-2.0.json diff --git a/schema/2.0/cyclonedx-2.0.schema.json b/schema/2.0/cyclonedx-2.0.schema.json index 2085d92d..98804d10 100644 --- a/schema/2.0/cyclonedx-2.0.schema.json +++ b/schema/2.0/cyclonedx-2.0.schema.json @@ -85,8 +85,8 @@ "externalReferences": { "$ref": "model/cyclonedx-common-2.0.schema.json#/$defs/externalReferences" }, - "signature": { - "$ref": "model/cyclonedx-common-2.0.schema.json#/$defs/signature" + "signatures": { + "$ref": "model/cyclonedx-common-2.0.schema.json#/$defs/signatures" } }, "allOf": [ 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 7bad85c9..c6069583 100644 --- a/schema/2.0/model/cyclonedx-annotation-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-annotation-2.0.schema.json @@ -104,8 +104,8 @@ "title": "Text", "description": "The textual content of the annotation." }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } 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 c95805a5..b08f2856 100644 --- a/schema/2.0/model/cyclonedx-citation-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-citation-2.0.schema.json @@ -65,8 +65,8 @@ "title": "Note", "description": "A description or comment about the context or quality of the data attribution." }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "A digital signature verifying the authenticity or integrity of the attribution." } 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 b93946c4..8684df5e 100644 --- a/schema/2.0/model/cyclonedx-common-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-common-2.0.schema.json @@ -763,10 +763,10 @@ "title": "Locale", "description": "Defines a syntax for representing two character language code (ISO-639) followed by an optional two character country code. The language code must be lower case. If the country code is specified, the country code must be upper case. The language code and country code must be separated by a minus sign. Examples: en, en-US, fr, fr-CA" }, - "signature": { - "$ref": "../jsf-0.82.schema.json#/definitions/signature", - "title": "Signature", - "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." + "signatures": { + "$ref": "cyclonedx-jss_X590_2023_10-2.0.schema.json#/$defs/signatures", + "title": "Signatures", + "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)." } } } 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 b7d540e0..086a6559 100644 --- a/schema/2.0/model/cyclonedx-component-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-component-2.0.schema.json @@ -274,8 +274,8 @@ "externalReferences": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } diff --git a/schema/2.0/model/cyclonedx-composition-2.0.schema.json b/schema/2.0/model/cyclonedx-composition-2.0.schema.json index 8aa2f6aa..792b139f 100644 --- a/schema/2.0/model/cyclonedx-composition-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-composition-2.0.schema.json @@ -66,8 +66,8 @@ "title": "BOM references", "description": "The bom-ref identifiers of the vulnerabilities being described." }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } 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 5920ec6f..2a0f522e 100644 --- a/schema/2.0/model/cyclonedx-declaration-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-declaration-2.0.schema.json @@ -133,8 +133,8 @@ } } }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } @@ -191,8 +191,8 @@ "externalReferences": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } @@ -296,8 +296,8 @@ "title": "Reviewer", "description": "The reviewer of the evidence." }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } @@ -369,8 +369,8 @@ "title": "Role", "description": "The signatory's role within an organization." }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." }, @@ -385,15 +385,15 @@ } } }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } } }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } 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 new file mode 100644 index 00000000..180c2133 --- /dev/null +++ b/schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json @@ -0,0 +1,259 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cyclonedx.org/schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json", + "type": "null", + "title": "CycloneDX Model for JSON Signature Scheme (JSS)", + "$comment" : "OWASP CycloneDX is an Ecma International standard (ECMA-424) developed in collaboration between the OWASP Foundation and Ecma Technical Committee 54 (TC54). The standard is published under a royalty-free patent policy. This JSON schema is the reference implementation and is licensed under the Apache License 2.0.", + "description": "JSON Schema implementing ITU-T X.590 (10/2023) – JSON Signature Scheme (JSS). Defines the structure for digitally signing JSON objects while keeping the payload in JSON format. Supports single signatures, multiple independent signatures, and chained counter-signatures. Intended for use as a $defs import in CycloneDX 2.0.", + "$defs": { + "timestamp": { + "title": "Timestamp", + "description": "An RFC 3339 timestamp in the UTC+0 time zone. Must use the 'Z' suffix. Sub-second precision, when present, MUST be exactly three digits (millisecond precision). If no sub-second digits are included, the decimal point MUST NOT be present. Matches the pattern: yyyy-mm-ddThh:mm:ss[.sss]Z", + "$comment": "Normative source: ITU-T X.590 clause 6.1", + "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]{3})?Z$", + "examples": [ + "2023-10-29T13:56:08Z", + "2023-10-29T13:56:08.000Z", + "2023-11-15T08:30:00.123Z" + ] + }, + "identifier": { + "title": "Identifier", + "description": "A Universally Unique Identifier (UUID) conformant with RFC 4122. Used to uniquely identify a signature object. Signatures sharing the same 'id' are treated as versions of the same logical signature, differentiated by their 'modified' timestamp.", + "$comment": "Normative source: ITU-T X.590 clause 6.1", + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", + "examples": [ + "f47ac10b-58cc-4372-a567-0e02b2c3d479" + ] + }, + "hashAlgorithm": { + "title": "Hash Algorithm", + "description": "This property identifies the hashing algorithm, as defined by the Internet Assigned Numbers Authority (IANA)…, that was used to hash the JCS version of the full JSON object (JSON Object + JSS Signature) and is a case-sensitive ASCII string. Implementations MAY use any current and widely accepted hashing algorithm (e.g., sha-256, sha-512) that is defined in the IANA registry. The actual signing process, defined in the algorithm property, sometimes uses an internal hashing algorithm inside the signing process itself, this property MAY identify the same hashing algorithm as the signing process or MAY identify a different hashing algorithm.", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1", + "type": "string", + "examples": [ + "sha-256", + "sha-384", + "sha-512", + "sha3-256", + "sha3-512" + ] + }, + "algorithmVocabulary": { + "title": "Signature Algorithm Type Vocabulary (signature-algorithm-type-ov)", + "description": "NOTE – At the time of this writing quantum safe algorithms could come from those defined in XMSS [IETF RFC 8391] section 5.3 or LMS [IETF RFC 8554] section 5.1 and other algorithms could come from those defined in JWA [IETF RFC 7518] section 3.1 or [IETF RFC 8037] section 3.1 (see the table below for a list of values from those RFCs). While JWA [IETF RFC 7518] section 3.1 defines the following symmetric algorithms: HS256, HS384, and HS512, these algorithms SHOULD NOT be used. If one of these three symmetric algorithms is used, the sharing and transmission of those keys is out of scope for this Recommendation.", + "$comment": "Normative source: ITU-T X.590 clause 6.2.2 and Table 1", + "type": "string", + "enum": [ + "XMSS-SHA2_10_256", + "XMSS-SHA2_16_256", + "XMSS-SHA2_20_256", + "LMS_SHA256_M32_H5", + "LMS_SHA256_M32_H10", + "LMS_SHA256_M32_H15", + "LMS_SHA256_M32_H20", + "LMS_SHA256_M32_H25", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512", + "Ed25519", + "Ed448" + ] + }, + "algorithm": { + "title": "Signing Algorithm", + "description": "This property identifies the algorithm that was used to sign the JSON data and is a case-sensitive ASCII string. The value for this property SHOULD come from the signature-algorithm-type-ov vocabulary (see clause 6.2.2) and SHOULD be a current and widely accepted quantum safe algorithm, but MAY use any currently accepted safe algorithm.", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1", + "type": "string", + "examples": [ + "Ed25519", + "ES256", + "XMSS-SHA2_10_256", + "LMS_SHA256_M32_H5", + "PS512" + ] + }, + "publicKey": { + "title": "Public Key (PEM, header-stripped)", + "description": "This property contains a privacy enhanced mail (PEM) encoded public key without the header and footer for the algorithm selected in the algorithm property.", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1", + "type": "string", + "examples": [ + "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=" + ] + }, + "publicCertChain": { + "title": "Public Certificate Chain", + "description": "This property contains a public key certificate for the algorithm selected in the algorithm property and MUST follow the requirements defined in section 4.7 of [IETF RFC 7517] as quoted here. This property \"contains a chain (X.509 certificate chain) of one or more PKIX certificates [IETF RFC 5280]. The certificate chain is represented as a JSON array of certificate value strings. Each string in the array is a base64-encoded (section 4 of [IETF RFC 4648] – not base64URL.encoded) DER [b-ITU-T X.690] PKIX certificate value. The PKIX certificate containing the key value MUST be the first certificate. This MAY be followed by additional certificates, with each subsequent certificate being the one used to certify the previous one. The key in the first certificate MUST match the public key.\" This property is called \"x5c\" in section 4.7 of [IETF RFC 7517].", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1", + "type": "array", + "items": { + "type": "string", + "description": "Base64-encoded (standard, not base64URL) DER-encoded PKIX certificate value (RFC 5280)." + }, + "minItems": 1 + }, + "certUrl": { + "title": "Certificate URL", + "description": "This property contains a uniform resource identifier (URI) [IETF RFC 3986] that refers to a resource for an X.509 public key certificate or certificate chain [IETF RFC 5280] for the algorithm selected in the algorithm property and MUST follow the requirements defined in section 4.6 of [IETF RFC 7517] as quoted here. \"The identified resource MUST provide a representation of the certificate or certificate chain that conforms to RFC 5280 [IETF RFC 5280] in PEM-encoded form, with each certificate delimited as specified in section 6.1 of RFC 4945 [IETF RFC 4945]. The key in the first certificate MUST match the public key. The protocol used to acquire the resource MUST provide integrity protection; an HTTP GET request to retrieve the certificate MUST use TLS [IETF RFC 2818] [IETF RFC 5246]; the identity of the server MUST be validated, as per section 6 of RFC 6125 [IETF RFC 6125].\" This property is called \"x5u\" in section 4.6 of [IETF RFC 7517].", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1", + "type": "string", + "format": "uri", + "pattern": "^https://", + "examples": [ + "https://pki.example.com/certs/signing-cert.pem" + ] + }, + "thumbprint": { + "title": "Certificate Thumbprint", + "description": "This property contains a fingerprint of a public key or public key certificate for the algorithm selected in the algorithm property and MUST follow the requirements defined in section 4.9 of [IETF RFC 7517] as quoted here. This property \"is a base64URL.encoded SHA-256 thumbprint (a.k.a. digest, X.509 certificate SHA-256 thumbprint) of the DER encoding of an X.509 certificate [IETF RFC 5280]. Note that certificate thumbprints are also sometimes known as certificate fingerprints. The key in the certificate MUST match the public key.\" This property is called \"x5t#S256\" in section 4.9 of [IETF RFC 7517].", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1", + "type": "string", + "examples": [ + "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs" + ] + }, + "signatureObject": { + "title": "Signature Object", + "description": "A JSS signature object as defined in ITU-T X.590 clause 6.2. Captures the hashing algorithm, signing algorithm, public key material (in one of four forms), the base64URL-encoded digital signature value, and optional metadata. May nest a child 'signature' property to form a counter-signature chain.", + "$comment": "Normative source: ITU-T X.590 clauses 6.2 and 6.3", + "type": "object", + "properties": { + "hash_algorithm": { + "$ref": "#/$defs/hashAlgorithm" + }, + "algorithm": { + "$ref": "#/$defs/algorithm" + }, + "public_key": { + "$ref": "#/$defs/publicKey" + }, + "public_cert_chain": { + "$ref": "#/$defs/publicCertChain" + }, + "cert_url": { + "$ref": "#/$defs/certUrl" + }, + "thumbprint": { + "$ref": "#/$defs/thumbprint" + }, + "value": { + "title": "Signature Value", + "description": "A base64URL.encoded signature that was created using the signature algorithm defined in the algorithm property and a key. In pseudo code it is defined as: base64URL.encode(sign(algorithm, key, hash(jcs()))).", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1", + "type": "string" + }, + "signature": { + "$ref": "#/$defs/signatureObject", + "title": "Counter-Signature", + "description": "This property enables a signature to be countersigned, meaning a signature can be signed by another signature.", + "$comment": "Normative source: ITU-T X.590 clause 6.2.1" + }, + "type": { + "title": "Type Indicator", + "description": "The value of this property MUST be jss.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1", + "type": "string", + "const": "jss" + }, + "id": { + "$ref": "#/$defs/identifier", + "title": "Signature Identifier", + "description": "A value that uniquely identifies the signature. All signatures with the same ID are considered different versions of the same signature and the version of the signature is identified by its modified property.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1" + }, + "related_to": { + "title": "Related Object Reference", + "description": "A value that can identify the original JSON object that was signed with this signature. If the signature is detached from the original JSON object this property SHOULD be populated.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1", + "type": "string" + }, + "related_version": { + "title": "Related Object Version", + "description": "A value that can identify the version of the original JSON object that was signed with this signature. If the signature is detached from the original JSON object this property SHOULD be populated.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1", + "type": "string" + }, + "created": { + "$ref": "#/$defs/timestamp", + "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$" + }, + "modified": { + "$ref": "#/$defs/timestamp", + "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", + "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$" + }, + "revoked": { + "title": "Revoked Flag", + "description": "A boolean that identifies if the signature creator deems that this signature is no longer valid. The default value is false.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1", + "type": "boolean", + "default": false + }, + "signee": { + "title": "Signee", + "description": "An unstructured string value for the name of the entity or organization that produced this signature.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1", + "type": "string" + }, + "valid_from": { + "$ref": "#/$defs/timestamp", + "title": "Valid From", + "description": "The time from which this signature is considered valid. If omitted, the signature is valid at all times or until the timestamp defined by valid_until. If the revoked property is true then this property MUST be ignored.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1" + }, + "valid_until": { + "$ref": "#/$defs/timestamp", + "title": "Valid Until", + "description": "The time at which this signature is no longer considered valid. If the valid_until property is omitted, then there is no constraint on the latest time for which the signature is valid. This property MUST be greater than the timestamp in the valid_from property if the valid_from property is defined. If the revoked property is true then this property MUST be ignored.", + "$comment": "Normative source: ITU-T X.590 clause 6.3.1" + } + }, + "required": ["hash_algorithm", "algorithm", "value"], + "anyOf": [ + { + "required": ["public_key"], + "description": "Public key material provided as PEM-encoded public key (header/footer stripped)." + }, + { + "required": ["public_cert_chain"], + "description": "Public key material provided as a base64-encoded DER X.509 certificate chain." + }, + { + "required": ["cert_url"], + "description": "Public key material provided by reference to a TLS-accessible certificate URI." + }, + { + "required": ["thumbprint"], + "description": "Public key material referenced by a base64URL-encoded SHA-256 certificate thumbprint." + } + ], + "unevaluatedProperties": true, + "$comment": "unevaluatedProperties: true is intentional. ITU-T X.590 clause 6.2 explicitly states that implementers MAY add additional properties to satisfy meta-data requirements for their application. The clause 6.3 properties (type, id, related_to, etc.) are themselves defined as non-exhaustive examples of such extensions." + }, + "signatures": { + "title": "Signatures Array", + "description": "A JSON array of one or more signature objects. MUST be located at the top-level of the signed JSON object. The property name used to hold this array SHOULD be 'signatures', but implementations MAY use a different name provided it does not conflict with any other top-level property name in the host JSON object. All signature objects in this array are independent parallel signatures over the same JSON object; for chained counter-signatures, use the nested 'signature' property within an individual signature object.", + "$comment": "Normative source: ITU-T X.590 clause 6 – 'The property that holds the signature MUST be a JSON list property and MUST be located at the top-level of the original JSON object.'", + "type": "array", + "items": { + "$ref": "#/$defs/signatureObject" + }, + "minItems": 1 + } + } +} diff --git a/schema/2.0/model/cyclonedx-service-2.0.schema.json b/schema/2.0/model/cyclonedx-service-2.0.schema.json index 7e02aeaf..64fab610 100644 --- a/schema/2.0/model/cyclonedx-service-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-service-2.0.schema.json @@ -112,8 +112,8 @@ "$ref": "cyclonedx-common-2.0.schema.json#/$defs/tags", "title": "Tags" }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } diff --git a/schema/2.0/model/cyclonedx-standard-2.0.schema.json b/schema/2.0/model/cyclonedx-standard-2.0.schema.json index 028a69c2..dfc31b49 100644 --- a/schema/2.0/model/cyclonedx-standard-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-standard-2.0.schema.json @@ -53,8 +53,8 @@ "externalReferences": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" }, - "signature": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signature", + "signatures": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/signatures", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-created-no-millis-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-created-no-millis-2.0.json new file mode 100644 index 00000000..8fa3a989 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-created-no-millis-2.0.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg", + "created": "2023-10-29T13:56:08Z" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-empty-cert-chain-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-empty-cert-chain-2.0.json new file mode 100644 index 00000000..2c9dc638 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-empty-cert-chain-2.0.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [], + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-empty-signatures-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-empty-signatures-2.0.json new file mode 100644 index 00000000..e339d2e6 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-empty-signatures-2.0.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-invalid-timestamp-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-invalid-timestamp-2.0.json new file mode 100644 index 00000000..66debc69 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-invalid-timestamp-2.0.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg", + "valid_from": "2023-10-29T13:56:08+05:00" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-missing-algorithm-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-missing-algorithm-2.0.json new file mode 100644 index 00000000..e1246d14 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-missing-algorithm-2.0.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-missing-hash-algorithm-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-missing-hash-algorithm-2.0.json new file mode 100644 index 00000000..4694cc2d --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-missing-hash-algorithm-2.0.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-missing-value-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-missing-value-2.0.json new file mode 100644 index 00000000..2aa0bf47 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-missing-value-2.0.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-modified-no-millis-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-modified-no-millis-2.0.json new file mode 100644 index 00000000..5abeb092 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-modified-no-millis-2.0.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg", + "modified": "2023-10-29T13:56:08Z" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-no-key-material-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-no-key-material-2.0.json new file mode 100644 index 00000000..389cf26c --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-no-key-material-2.0.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + } + ] +} diff --git a/tools/src/test/resources/2.0/invalid-jss-signature-type-not-jss-2.0.json b/tools/src/test/resources/2.0/invalid-jss-signature-type-not-jss-2.0.json new file mode 100644 index 00000000..e19ac39f --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-jss-signature-type-not-jss-2.0.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg", + "type": "jwt" + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-cert-url-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-cert-url-2.0.json new file mode 100644 index 00000000..0237a15f --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-cert-url-2.0.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-512", + "algorithm": "RS256", + "cert_url": "https://pki.example.com/certs/signing-cert.pem", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-counter-signature-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-counter-signature-2.0.json new file mode 100644 index 00000000..3246ba44 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-counter-signature-2.0.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg", + "signature": { + "hash_algorithm": "sha-512", + "algorithm": "ES256", + "thumbprint": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", + "value": "tqITqIm0gUMWXIjqDgwqzqPw1CwTUKRewZQ5YpX3VwFMWV68NJgX4npU91cSwSC-MRlx1QfOYwSQkeU26VpXSg" + } + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-custom-properties-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-custom-properties-2.0.json new file mode 100644 index 00000000..8060ce2b --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-custom-properties-2.0.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg", + "custom_metadata_1": "some-application-specific-value", + "custom_metadata_2": 42 + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-metadata-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-metadata-2.0.json new file mode 100644 index 00000000..40764c07 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-metadata-2.0.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg", + "type": "jss", + "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", + "related_to": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "related_version": "1", + "created": "2023-10-29T13:56:08.000Z", + "modified": "2023-10-29T13:56:08.000Z", + "revoked": false, + "signee": "ACME Inc.", + "valid_from": "2023-10-29T13:56:08Z", + "valid_until": "2025-10-29T13:56:08Z" + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-multiple-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-multiple-2.0.json new file mode 100644 index 00000000..a8796934 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-multiple-2.0.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + }, + { + "hash_algorithm": "sha-512", + "algorithm": "ES384", + "thumbprint": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", + "value": "tqITqIm0gUMWXIjqDgwqzqPw1CwTUKRewZQ5YpX3VwFMWV68NJgX4npU91cSwSC-MRlx1QfOYwSQkeU26VpXSg" + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-public-cert-chain-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-public-cert-chain-2.0.json new file mode 100644 index 00000000..d16b6ef6 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-public-cert-chain-2.0.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "ES256", + "public_cert_chain": [ + "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8" + ], + "value": "tqITqIm0gUMWXIjqDgwqzqPw1CwTUKRewZQ5YpX3VwFMWV68NJgX4npU91cSwSC-MRlx1QfOYwSQkeU26VpXSg" + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-public-key-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-public-key-2.0.json new file mode 100644 index 00000000..4c733481 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-public-key-2.0.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "Ed25519", + "public_key": "MCowBQYDK2VwAyEAubMonBfU9pvIbj5RCiWQLD45Jvu6mKr+kQXjvjW8ZkU=", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-jss-signature-thumbprint-2.0.json b/tools/src/test/resources/2.0/valid-jss-signature-thumbprint-2.0.json new file mode 100644 index 00000000..19eb9d9a --- /dev/null +++ b/tools/src/test/resources/2.0/valid-jss-signature-thumbprint-2.0.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:1b1bff0e-fdb9-4088-8b9a-1a9f2d9006da", + "version": 1, + "components": [ + { + "type": "library", + "name": "my-library", + "version": "1.0" + } + ], + "signatures": [ + { + "hash_algorithm": "sha-256", + "algorithm": "PS256", + "thumbprint": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", + "value": "F1Sj4VcZlSt5GO3Bcu4izpCklj9DbKDNvc2Trpdznfqgv9HMPUGVtefMsHfTqel-dN20lUXsdoeD8PpVr1ssCg" + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-signatures-2.0.json b/tools/src/test/resources/2.0/valid-signatures-2.0.json deleted file mode 100644 index 260cf202..00000000 --- a/tools/src/test/resources/2.0/valid-signatures-2.0.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "$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": [ - { - "bom-ref": "5366293e-0740-4dcf-b1d0-0c1fc26e4981", - "type": "application", - "name": "amce app", - "version": "1.0", - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", - "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" - ], - "value": "tqITqIm0gUMWXIjqDgwqzqPw1CwTUKRewZQ5YpX3VwFMWV68NJgX4npU91cSwSC-MRlx1QfOYwSQkeU26VpXSg" - } - } - ], - "services": [ - { - "bom-ref": "ee10d0a2-baba-4656-a5ac-d49e172a0d3d", - "group": "org.partner", - "name": "Stock ticker service", - "version": "2020-Q2", - "endpoints": [ - "https://partner.org/api/v1/lookup", - "https://partner.org/api/v1/stock" - ], - "authenticated": true, - "x-trust-boundary": true, - "data": [ - { - "classification": "PII", - "flow": "inbound" - } - ], - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", - "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" - ], - "value": "6A77T3RBTAuVpZOgFFFfOvGOQ1hqMbfSQ91VucRM1RIP6QqX9kEF1Pi1_vCl37qpVzK51kIyppgUF_i9s999XA" - } - } - ], - "compositions": [ - { - "aggregate": "complete", - "assemblies": [ - "5366293e-0740-4dcf-b1d0-0c1fc26e4981", - "ee10d0a2-baba-4656-a5ac-d49e172a0d3d" - ], - "dependencies": [ - "5366293e-0740-4dcf-b1d0-0c1fc26e4981" - ], - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", - "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" - ], - "value": "lm6wx-elyBTbNMKNF8riooZhvrm6f5j8JpvgP9JtVv50dd7sXQLH7PqJcn9fmKV8eoF8cszPllEsQQhEQOM4hA" - } - } - ], - "signature": { - "algorithm": "ES256", - "certificatePath": [ - "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", - "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" - ], - "value": "m4pMbQQVV61TlP4Og7a75SeY8lh00LkkUDXZ4PIhXsR512MPRgZmusFYorJlYq9wM3P9n9gM3T8BTg9XdFdQkQ" - } -}