From 2d8ea2f2787fedba5cf8df8a2b2dba978b2e760e Mon Sep 17 00:00:00 2001 From: Daniel Stahl Date: Tue, 7 Aug 2018 15:27:20 +0200 Subject: [PATCH 1/9] Intermediary commit addressing issue 185 Changed documentation, schema and example of EiffelArtifactPublishedEvent. This is intended to enable review and discussion of the solution, before applying to all event types. --- .../EiffelArtifactPublishedEvent.md | 50 ++++- .../EiffelArtifactPublishedEvent/simple.json | 22 +- .../EiffelArtifactPublishedEvent/3.0.0.json | 191 ++++++++++++++++++ 3 files changed, 251 insertions(+), 12 deletions(-) create mode 100644 schemas/EiffelArtifactPublishedEvent/3.0.0.json diff --git a/eiffel-vocabulary/EiffelArtifactPublishedEvent.md b/eiffel-vocabulary/EiffelArtifactPublishedEvent.md index f250bd2e..aae89ab0 100644 --- a/eiffel-vocabulary/EiffelArtifactPublishedEvent.md +++ b/eiffel-vocabulary/EiffelArtifactPublishedEvent.md @@ -138,28 +138,64 @@ __Format:__ __Required:__ No __Description:__ An optional object for enclosing security related information, particularly supporting data integrity. See [Security](../eiffel-syntax-and-usage/security.md) for further information. -#### meta.security.sdm +#### meta.security.authorIdentity +__Type:__ String +__Format:__ [Distinguished Name](https://tools.ietf.org/html/rfc2253) +__Required:__ Yes +__Description:__ The identity of the author of the event. This property is intended to enable the recipient to identify the author of the event contents and/or look up the appropriate public key for decrypting the digest and thereby verifying author identity and data integrity. + +#### meta.security.integrityProtection __Type:__ Object __Format:__ __Required:__ No -__Description:__ An optional object for properties supporting the [Strong Distribution Model](http://www.cryptnet.net/fdp/crypto/strong_distro.html). Note that this only addressed the _integrity_ of the Eiffel event, not its _confidentiality_ or _availability_. +__Description:__ An optional object for enabling information integrity protection via cryptographic signing. IMPORTANT: To generate a correct __meta.security.integrityProtection__ object: +1. Generate the entire event, but with the __meta.security.integrityProtection.signature__ value set to an empty string. +1. Serialize the event on [Canonical JSON Form](https://tools.ietf.org/html/draft-staykov-hu-json-canonical-form-00). +1. Generate the signature using the __meta.security.integrityProtection.alg__ algorithm. +1. Set the __meta.security.integrityProtection.signature__ value to the resulting signature while maintaining Canonical JSON Form. +To verify the integrity of the event, the consumer then resets __meta.security.integrityProtection.signature__ to an empty string and ensures Canonical JSON Form before verifying the signature. + +##### meta.security.integrityProtection.alg +__Type:__ String +__Format:__ (A valid JWA RFC 7518 "alg" parameter value)[https://tools.ietf.org/html/rfc7518#section-3.1], excluding "none" +__Required:__ Yes +__Description:__ The cryptographic algorithm used to digitally sign the event. -##### meta.security.sdm.authorIdentity +##### meta.security.integrityProtection.signature __Type:__ String __Format:__ __Required:__ Yes -__Description:__ The identity of the author of the event. This property is intended to enable the recipient to look up the appropriate public key for decrypting the digest and thereby verifying author identity and data integrity. The format of the author identity varies depending on the key infrastructure solution used. Note that this requires the presence of a Trusted Authority (TA) which the recipient can query for the correct public key. The identity and location of the TA must never be included in the event itself, as this would compromise the security of the solution. +__Description:__ The signature produced by the signing algorithm. -##### meta.security.sdm.encryptedDigest +##### meta.security.integrityProtection.publicKey __Type:__ String __Format:__ +__Required:__ No +__Description:__ The producer of the event may include the relevant public key for convenience, rather than relying a separate key distribution mechanism. Note that this property, along with the rest of the event, is encompassed by the integrity protection offered via __meta.security.integrityProtection__. + +#### meta.security.sequenceProtection +__Type:__ Object[] +__Format:__ +__Required:__ No +__Description:__ An optional object for enabling verification of intact event sequences in a distributed environment, thereby protecting against data loss, race conditions and replay attacks. It allows event publishers to state the order in which they produce a certain set of events. In other words, it cannot provide any global guarantees as to event sequencing, but rather per-publisher guarantees. Every object in the array represents a named sequence of which this event forms a part. For every event including a given named sequence, the publisher SHALL increment __meta.security.sequenceProtection.position__ by 1. The first event produced in a given named sequence SHALL numbered 1. + +##### meta.security.sequenceProtection.sequenceName +__Type:__ String +__Format:__ +__Required:__ Yes +__Description:__ The name of the sequence. There MUST not be two identical __meta.security.sequenceProtection.sequenceName__ values in the same event. + +##### meta.security.sequenceProtection.sequenceName +__Type:__ Integer +__Format:__ __Required:__ Yes -__Description:__ The encrypted digest. The cryptographic hash function and the decryption algorithm to use, similarly to the Trusted Authority (TA), must be known to the recipient. Note that the digest of the entire event is affected by the value of this property. For this reason the input to the hash function SHALL be the entire event unaltered in all parts except for this property, which SHALL be replaced by an empty string. +__Description:__ The number of the event within the named sequence. ## Version History | Version | Introduced in | Changes | | --------- | ------------------------------------------------------ | --------------------------------------- | -| 2.0.0 | Current version | Introduced purl identifiers instead of GAVs (see [Issue 182](https://github.com/eiffel-community/eiffel/issues/182)) | +| 3.0.0 | Current version | Improved information integrity protection | (see [Issue 185](https://github.com/eiffel-community/eiffel/issues/185)) | +| 2.0.0 | [dc5ec6f](../../../blob/dc5ec6fb87e293eeffe88fdafe698eec0f5a2c89/eiffel-vocabulary/EiffelIssueVerifiedEvent.md) | Introduced purl identifiers instead of GAVs (see [Issue 182](https://github.com/eiffel-community/eiffel/issues/182)) | | 1.1.0 | [edition-toulouse](../../../tree/edition-toulouse) | Multiple links of type FLOW_CONTEXT allowed. | | 1.0.0 | [edition-bordeaux](../../../tree/edition-bordeaux) | Initial version. | diff --git a/examples/events/EiffelArtifactPublishedEvent/simple.json b/examples/events/EiffelArtifactPublishedEvent/simple.json index 7295f413..c5e46d35 100644 --- a/examples/events/EiffelArtifactPublishedEvent/simple.json +++ b/examples/events/EiffelArtifactPublishedEvent/simple.json @@ -1,14 +1,26 @@ { "meta": { "type": "EiffelArtifactPublishedEvent", - "version": "2.0.0", + "version": "3.0.0", "time": 1234567890, "id": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee0", "security": { - "sdm": { - "authorIdentity": "MyCompany/JohnDoe", - "encryptedDigest": "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" - } + "authorIdentity": "CN=John Doe,O=Awesome Company,C=Awesomeistan", + "integrityProtection": { + "signature": "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", + "alg": "HS256", + "publicKey": "really-long-string-containing-the-public-key-matching-the-private-key-used-to-generate-the-encrypted-digest" + }, + "sequenceProtection": [ + { + "sequenceName": "allEvents", + "position": 8734 + }, + { + "sequenceName": "deploymentEvents", + "position": 18 + } + ] } }, "data": { diff --git a/schemas/EiffelArtifactPublishedEvent/3.0.0.json b/schemas/EiffelArtifactPublishedEvent/3.0.0.json new file mode 100644 index 00000000..826aa6c5 --- /dev/null +++ b/schemas/EiffelArtifactPublishedEvent/3.0.0.json @@ -0,0 +1,191 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "meta": { + "type": "object", + "properties": { + "id": { + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "type": { + "type": "string", + "enum": ["EiffelArtifactPublishedEvent"] + }, + "version": { + "type": "string", + "enum": [ "3.0.0" ], + "default": "3.0.0" + }, + "time": { + "type": "integer" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "source": { + "type": "object", + "properties": { + "domainId": { + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "type": "string" + }, + "serializer": { + "type": "string", + "pattern": "^pkg:" + }, + "uri": { + "type": "string" + } + }, + "additionalProperties": false + }, + "security": { + "type": "object", + "properties": { + "authorIdentity": { + "type": "string" + }, + "integrityProtection": { + "type": "object", + "properties": { + "signature": { + "type": "string" + }, + "alg": { + "type": "string", + "enum": ["HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512"] + }, + "publicKey": { + "type": "string" + } + }, + "required": [ + "signature", + "alg" + ], + "additionalProperties": false + }, + "sequenceProtection": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sequenceName": { + "type": "string" + }, + "position": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "sequenceName", + "position" + ] + } + } + }, + "additionalProperties": false, + "required": [ + "authorIdentity" + ] + } + }, + "required": [ + "id", + "type", + "version", + "time" + ], + "additionalProperties": false + }, + "data": { + "type": "object", + "properties": { + "locations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "ARTIFACTORY", + "NEXUS", + "PLAIN", + "OTHER" + ] + }, + "uri": { + "type": "string" + } + }, + "required": [ + "type", + "uri" + ], + "additionalProperties": false + } + }, + "customData": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + } + }, + "required": [ + "key", + "value" + ], + "additionalProperties": false + } + } + }, + "required": [ + "locations" + ], + "additionalProperties": false + }, + "links": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "target": { + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + }, + "required": [ + "type", + "target" + ], + "additionalProperties": false + } + } + }, + "required": [ + "meta", + "data", + "links" + ], + "additionalProperties": false +} From 3fa6a596b113832e8c11b1b4f500d4a8d22e4c45 Mon Sep 17 00:00:00 2001 From: Daniel Stahl Date: Tue, 7 Aug 2018 15:33:02 +0200 Subject: [PATCH 2/9] Fixed typos and mistakes. --- eiffel-vocabulary/EiffelArtifactPublishedEvent.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eiffel-vocabulary/EiffelArtifactPublishedEvent.md b/eiffel-vocabulary/EiffelArtifactPublishedEvent.md index aae89ab0..991adb29 100644 --- a/eiffel-vocabulary/EiffelArtifactPublishedEvent.md +++ b/eiffel-vocabulary/EiffelArtifactPublishedEvent.md @@ -140,15 +140,15 @@ __Description:__ An optional object for enclosing security related information, #### meta.security.authorIdentity __Type:__ String -__Format:__ [Distinguished Name](https://tools.ietf.org/html/rfc2253) +__Format:__ [Distinguished Name](https://tools.ietf.org/html/rfc2253) __Required:__ Yes -__Description:__ The identity of the author of the event. This property is intended to enable the recipient to identify the author of the event contents and/or look up the appropriate public key for decrypting the digest and thereby verifying author identity and data integrity. +__Description:__ The identity of the author of the event. This property is intended to enable the recipient to identify the author of the event contents and/or look up the appropriate public key for decrypting the __meta.security.integrityProtection.signature__ value and thereby verifying author identity and data integrity. #### meta.security.integrityProtection __Type:__ Object __Format:__ __Required:__ No -__Description:__ An optional object for enabling information integrity protection via cryptographic signing. IMPORTANT: To generate a correct __meta.security.integrityProtection__ object: +__Description:__ An optional object for enabling information integrity protection via cryptographic signing. To generate a correct __meta.security.integrityProtection__ object: 1. Generate the entire event, but with the __meta.security.integrityProtection.signature__ value set to an empty string. 1. Serialize the event on [Canonical JSON Form](https://tools.ietf.org/html/draft-staykov-hu-json-canonical-form-00). 1. Generate the signature using the __meta.security.integrityProtection.alg__ algorithm. @@ -157,9 +157,9 @@ To verify the integrity of the event, the consumer then resets __meta.security.i ##### meta.security.integrityProtection.alg __Type:__ String -__Format:__ (A valid JWA RFC 7518 "alg" parameter value)[https://tools.ietf.org/html/rfc7518#section-3.1], excluding "none" +__Format:__ (A valid JWA RFC 7518 alg parameter value)[https://tools.ietf.org/html/rfc7518#section-3.1], excluding "none" __Required:__ Yes -__Description:__ The cryptographic algorithm used to digitally sign the event. +__Description:__ The cryptographic algorithm used to digitally sign the event. If no signing is performed, the __meta.security.integrityProtection__ SHALL be omitted rather than setting __meta.security.integrityProtection.alg__ to "none". ##### meta.security.integrityProtection.signature __Type:__ String From 40fbb4f5cd1332d6fdab4c8ce7fd7ba9dc97d2b2 Mon Sep 17 00:00:00 2001 From: Daniel Stahl Date: Tue, 7 Aug 2018 15:34:23 +0200 Subject: [PATCH 3/9] More mistakes. --- eiffel-vocabulary/EiffelArtifactPublishedEvent.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eiffel-vocabulary/EiffelArtifactPublishedEvent.md b/eiffel-vocabulary/EiffelArtifactPublishedEvent.md index 991adb29..1568f961 100644 --- a/eiffel-vocabulary/EiffelArtifactPublishedEvent.md +++ b/eiffel-vocabulary/EiffelArtifactPublishedEvent.md @@ -140,7 +140,7 @@ __Description:__ An optional object for enclosing security related information, #### meta.security.authorIdentity __Type:__ String -__Format:__ [Distinguished Name](https://tools.ietf.org/html/rfc2253) +__Format:__ [Distinguished Name](https://tools.ietf.org/html/rfc2253) __Required:__ Yes __Description:__ The identity of the author of the event. This property is intended to enable the recipient to identify the author of the event contents and/or look up the appropriate public key for decrypting the __meta.security.integrityProtection.signature__ value and thereby verifying author identity and data integrity. @@ -157,7 +157,7 @@ To verify the integrity of the event, the consumer then resets __meta.security.i ##### meta.security.integrityProtection.alg __Type:__ String -__Format:__ (A valid JWA RFC 7518 alg parameter value)[https://tools.ietf.org/html/rfc7518#section-3.1], excluding "none" +__Format:__ [A valid JWA RFC 7518 alg parameter value](https://tools.ietf.org/html/rfc7518#section-3.1), excluding "none" __Required:__ Yes __Description:__ The cryptographic algorithm used to digitally sign the event. If no signing is performed, the __meta.security.integrityProtection__ SHALL be omitted rather than setting __meta.security.integrityProtection.alg__ to "none". From 0aa176d2378f971be68da8225facdfed0fcccfca Mon Sep 17 00:00:00 2001 From: Daniel Stahl Date: Wed, 8 Aug 2018 09:01:20 +0200 Subject: [PATCH 4/9] Updated security.md --- eiffel-syntax-and-usage/security.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/eiffel-syntax-and-usage/security.md b/eiffel-syntax-and-usage/security.md index 37671325..964adf91 100644 --- a/eiffel-syntax-and-usage/security.md +++ b/eiffel-syntax-and-usage/security.md @@ -1,5 +1,5 @@