diff --git a/docs/spec-files/encryption.md b/docs/spec-files/encryption.md index 07dbd0e..ca94714 100644 --- a/docs/spec-files/encryption.md +++ b/docs/spec-files/encryption.md @@ -6,16 +6,25 @@ DIDComm Messages are encrypted with the keys of a single DID. A message being se DIDComm supports two types of message encryption: Authenticated Sender Encryption ("authcrypt") and Anonymous Sender Encryption ("anoncrypt"). Both forms are encrypted to the recipient DID. Only authcrypt provides direct assurances of who the sender is. Each encrypted message MUST use either authcrypt or anoncrypt. -The encrypted form of a JWM is a JWE in General JSON Format. The JOSE family defines [JSON Web Algorithms](https://tools.ietf.org/html/rfc7518) (JWAs) which standardize certain cryptographic operations that are related to preparing JOSE structures. For the purposes of interoperability, DIDComm messaging does not support all JWAs; rather, it takes a subset of the supported algorithms that are applicable for the following cases around secure messaging. These supported algorithms are listed in tables later in the spec. +When using JSON encoding, the encrypted form of a JWM is a JWE in General JSON Format. The JOSE family defines [JSON Web Algorithms](https://tools.ietf.org/html/rfc7518) (JWAs) which standardize certain cryptographic operations that are related to preparing JOSE structures. + +When using CBOR encoding, the encrypted form uses COSE (CBOR Object Signing and Encryption) as defined in [RFC 8152](https://tools.ietf.org/html/rfc8152). COSE_Encrypt or COSE_Encrypt0 structures are used for encryption operations. + +For the purposes of interoperability, DIDComm messaging does not support all JWAs or COSE algorithms; rather, it takes a subset of the supported algorithms that are applicable for the following cases around secure messaging. These supported algorithms are listed in tables later in the spec. #### Sender Authenticated Encryption -For an encrypted DIDComm message, the JWA of [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04) MUST be used within the structure of a JWE. +For an encrypted DIDComm message using JSON encoding, the JWA of [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04) MUST be used within the structure of a JWE. + +For an encrypted DIDComm message using CBOR encoding, the equivalent COSE algorithm ECDH-1PU (as defined in [draft-madden-cose-ecdh-1pu](https://datatracker.ietf.org/doc/draft-madden-cose-ecdh-1pu/)) MUST be used within the structure of a COSE_Encrypt or COSE_Encrypt0. #### Anonymous Encryption -When a sender would like to encrypt a message for a recipient DID or multiple recipient DIDs but not be authenticated by the recipients, the JWA of `ECDH-ES` defined by [RFC 7518](https://tools.ietf.org/html/rfc7518#section-4.6) SHOULD be used within the structure of a JWE. +When a sender would like to encrypt a message for a recipient DID or multiple recipient DIDs but not be authenticated by the recipients, the following SHOULD be used: + +- For JSON encoding: the JWA of `ECDH-ES` defined by [RFC 7518](https://tools.ietf.org/html/rfc7518#section-4.6) within the structure of a JWE. +- For CBOR encoding: the COSE algorithm ECDH-ES defined by [RFC 8152](https://tools.ietf.org/html/rfc8152) within the structure of a COSE_Encrypt or COSE_Encrypt0. Anonymous encryption removes authentication of the sender, which is a significant benefit of DIDComm Messaging; it may make sense, but should only be done thoughtfully, when the context of the use case justifies it. Pairing anonymous encryption with a method of message authentication other than authcrypt as defined in this specification is not generally recommended, as it may have unintended side effects. In particular, a signed message that is anonymously encrypted accomplishes authentication, but loses the repudiability of authcrypt. Further discussion of message authentication can be found in the [DIDComm Guidebook](https://didcomm.org/book/v2). @@ -30,21 +39,24 @@ For the keys involved in key agreement, the first three elliptic curves in this | P-256 | NIST defined P-256 elliptic curve - deprecated in favor of P-384 | | P-521 | NIST defined P-521 elliptic curve. Optional. | -For content encryption of the message, DIDComm inherits the implementation definitions from [JSON Web Algorithms](https://datatracker.ietf.org/doc/html/rfc7518#section-5.1) for AES 256-bit keys. -In addition, DIDComm defines optional implementation usage of the draft [XC20P](https://tools.ietf.org/id/draft-amringer-jose-chacha-02.html) algorithm. +For content encryption of the message when using JSON encoding, DIDComm inherits the implementation definitions from [JSON Web Algorithms](https://datatracker.ietf.org/doc/html/rfc7518#section-5.1) for AES 256-bit keys. In addition, DIDComm defines optional implementation usage of the draft [XC20P](https://tools.ietf.org/id/draft-amringer-jose-chacha-02.html) algorithm. + +For content encryption of the message when using CBOR encoding, DIDComm uses the equivalent algorithms defined in [COSE Algorithms](https://www.iana.org/assignments/cose/cose.xhtml#algorithms). To prevent invalid curve and weak point attacks, implementations that decrypt messages from a NIST curve MUST verify that the received public key (contained in the JWE protected header) is on the curve in question. This check may already be done by some JOSE libraries, but developers should not assume this is the case. See [this explanation](http://blog.intothesymmetry.com/2017/03/critical-vulnerability-in-json-web.html) of the risk, and [this practical guide](https://neilmadden.blog/2017/05/17/so-how-do-you-validate-nist-ecdh-public-keys/) for how to perform the verification correctly. -| Algorithm(JWA) | Description | Authcrypt/Anoncrypt | Requirements | +| Algorithm(JWA/COSE) | Description | Authcrypt/Anoncrypt | Requirements | | -------------- | -------------------------- |------------------------------- |------------------------------- | -| A256CBC-HS512 | AES256-CBC + HMAC-SHA512 with a 512 bit key | Authcrypt/Anoncrypt | Required | -| A256GCM | AES256-GCM with a 256 bit key | Anoncrypt | Recommended | -| XC20P | XChaCha20Poly1305 with a 256 bit key | Anoncrypt | Optional | +| A256CBC-HS512 (JWA) / HMAC-SHA-512+AES-256-CBC (COSE) | AES256-CBC + HMAC-SHA512 with a 512 bit key | Authcrypt/Anoncrypt | Required | +| A256GCM (JWA) / A256GCM (COSE) | AES256-GCM with a 256 bit key | Anoncrypt | Recommended | +| XC20P (JWA) / XC20P (COSE) | XChaCha20Poly1305 with a 256 bit key | Anoncrypt | Optional | Implementations MUST choose nonces securely. #### Key Wrapping Algorithms +##### JSON Encoding (JWA) + | KW Algorithm | Curve (epk crv) | key type (epk kty) | Description | | --------------- | --------------- | ------------------ | ------------------------------------------------------------ | | ECDH-ES+A256KW | P-256 | EC | ECDH-ES key wrapping using key with NIST defined P-256 elliptic curve to create a 256 bits key as defined in [RFC 7518](https://tools.ietf.org/html/rfc7518#section-4.6.2) | @@ -56,6 +68,19 @@ Implementations MUST choose nonces securely. | ECDH-1PU+A256KW | P-521 | EC | ECDH-1PU key wrapping using key with NIST defined P-521 elliptic curve to create a 512 bits key as defined in [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04#section-2) | | ECDH-1PU+A256KW | X25519 | OKP | ECDH-1PU X25519 ([RFC7748 section 5](https://tools.ietf.org/html/rfc7748#section-5)) to create a 256 bits key as defined in [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04#section-2) | +##### CBOR Encoding (COSE) + +| KW Algorithm | Curve (epk crv) | key type (epk kty) | Description | +| --------------- | --------------- | ------------------ | ------------------------------------------------------------ | +| ECDH-ES+A256KW | P-256 | EC2 | ECDH-ES key wrapping using key with NIST defined P-256 elliptic curve to create a 256 bits key as defined in [RFC 8152](https://tools.ietf.org/html/rfc8152) | +| ECDH-ES+A256KW | P-384 | EC2 | ECDH-ES key wrapping using key with NIST defined P-384 elliptic curve to create a 256 bits key as defined in [RFC 8152](https://tools.ietf.org/html/rfc8152) | +| ECDH-ES+A256KW | P-521 | EC2 | ECDH-ES key wrapping using key with NIST defined P-521 elliptic curve to create a 512 bits key as defined in [RFC 8152](https://tools.ietf.org/html/rfc8152) | +| ECDH-ES+A256KW | X25519 | OKP | ECDH-ES with X25519 ([RFC 7748 section 5](https://tools.ietf.org/html/rfc7748#section-5)) to create a 256 bits key. The underlying curve is actually `Curve25519`, however when used in the context of Diffie-Hellman the identifier of `X25519` is used | +| ECDH-1PU+A256KW | P-256 | EC2 | ECDH-1PU key wrapping using key with NIST defined P-256 elliptic curve to create a 256 bits key as defined in [draft-madden-cose-ecdh-1pu](https://datatracker.ietf.org/doc/draft-madden-cose-ecdh-1pu/) | +| ECDH-1PU+A256KW | P-384 | EC2 | ECDH-1PU key wrapping using key with NIST defined P-384 elliptic curve to create a 256 bits key as defined in [draft-madden-cose-ecdh-1pu](https://datatracker.ietf.org/doc/draft-madden-cose-ecdh-1pu/) | +| ECDH-1PU+A256KW | P-521 | EC2 | ECDH-1PU key wrapping using key with NIST defined P-521 elliptic curve to create a 512 bits key as defined in [draft-madden-cose-ecdh-1pu](https://datatracker.ietf.org/doc/draft-madden-cose-ecdh-1pu/) | +| ECDH-1PU+A256KW | X25519 | OKP | ECDH-1PU X25519 ([RFC7748 section 5](https://tools.ietf.org/html/rfc7748#section-5)) to create a 256 bits key as defined in [draft-madden-cose-ecdh-1pu](https://datatracker.ietf.org/doc/draft-madden-cose-ecdh-1pu/) | + #### Perfect Forward Secrecy The mapping of the Perfect Forward Secrecy concepts to DIDComm requires some discussion, due to the lack of a session construct. Please refer to the [DIDComm Guidebook](https://didcomm.org/book/v2/pfs) for details. @@ -129,7 +154,10 @@ If two communicating parties establish single-purpose DIDs (e.g., peer DIDs) for A layer of anonymous encryption (employing ECDH-ES) may be applied around an authenticated encryption envelope (employing ECDH-1PU), obscuring the sender's identity for all but the recipient of the inner envelope. In the case of a message forwarded via mediators, anonymous encryption is automatic. #### ECDH-1PU key wrapping and common protected headers -When using authcrypt, the 1PU draft [mandates](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04#section-2.1) the use of the AES_CBC_HMAC_SHA family of content encryption algorithms. To meet this requirement, JWE messages MUST use common `epk`, `apu`, `apv` and `alg` headers for all recipient keys. They MUST be set in the `protected` JWE section. + +##### JSON Encoding (JWE) + +When using authcrypt with JSON encoding, the 1PU draft [mandates](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04#section-2.1) the use of the AES_CBC_HMAC_SHA family of content encryption algorithms. To meet this requirement, JWE messages MUST use common `epk`, `apu`, `apv` and `alg` headers for all recipient keys. They MUST be set in the `protected` JWE section. As per this requirement, the JWE building must first encrypt the payload, then use the resulting `tag` as part of the key derivation process when wrapping the `cek`. @@ -146,9 +174,22 @@ Even though `apu`/`apv` are not mandatory JWE recipients headers, they are requi A final note about `skid` header: since the 1PU draft [does not require](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04#section-2.2.1) this header, authcrypt implementations MUST be able to resolve the sender kid from the `apu` header if `skid` is not set. +##### CBOR Encoding (COSE) + +When using authcrypt with CBOR encoding, the equivalent COSE headers MUST be used: + +* `ephemeral key`: equivalent to JWE's `epk`, generated once for all recipient keys. It MUST be of the same type and curve as all recipient keys. +* `party u identity`: equivalent to JWE's `apu`, this is the producer (sender) identifier. +* `party v identity`: equivalent to JWE's `apv`, this represents the recipients' identifiers. +* `algorithm`: equivalent to JWE's `alg`, this is the key wrapping algorithm. + +The same requirements for content encryption algorithms and key derivation process apply to COSE as they do for JWE. + #### ECDH-ES key wrapping and common protected headers -When using anoncrypt, any of the valid content encryption algorithms may be used. To meet this requirement, JWE messages MUST use common `epk`, `apv` and `alg` headers for all recipient keys. They MUST be set in the `protected` JWE section. +##### JSON Encoding (JWE) + +When using anoncrypt with JSON encoding, any of the valid content encryption algorithms may be used. To meet this requirement, JWE messages MUST use common `epk`, `apv` and `alg` headers for all recipient keys. They MUST be set in the `protected` JWE section. As per this requirement, the JWE building must first encrypt the payload, then use the resulting `tag` as part of the key derivation process when wrapping the `cek`. @@ -159,8 +200,31 @@ To meet this requirement, the above headers are defined as follows: * `apv`: this represents the recipients' `kid` list. The list must be alphanumerically sorted, `kid` values will then be concatenated with a `.` and the final result MUST be base64 URL (no padding) encoding of the SHA256 hash of concatenated list. * `alg`: this is the key wrapping algorithm, ie: `ECDH-ES+A256KW`. -Note: `apu`will not be present when using ECDH-ES. +Note: `apu` will not be present when using ECDH-ES. + +##### CBOR Encoding (COSE) + +When using anoncrypt with CBOR encoding, the equivalent COSE headers MUST be used: + +* `ephemeral key`: equivalent to JWE's `epk`, generated once for all recipient keys. +* `party v identity`: equivalent to JWE's `apv`, this represents the recipients' identifiers. +* `algorithm`: equivalent to JWE's `alg`, this is the key wrapping algorithm. + +Note: `party u identity` will not be present when using ECDH-ES. #### Examples While the details of encrypting a JWM into a JWE are included in the [JWM spec](https://tools.ietf.org/html/draft-looker-jwm-01), a few examples are included here for clarity. See section [Appendix C.3](#c3-didcomm-encrypted-messages). + +For CBOR encoding, the equivalent COSE structures would be used. The CBOR encoding would represent the same data structures but in the more compact CBOR binary format. + +##### CBOR Encoding Considerations + +When implementing CBOR encoding for DIDComm messages, the following considerations should be taken into account: + +1. COSE structures use a more compact representation than JWE, which can significantly reduce message size. +2. COSE uses integer labels for header parameters instead of string keys, further reducing size. +3. When converting between JSON and CBOR representations, care must be taken to ensure all security properties are preserved. +4. Implementations should provide clear error messages when encountering encoding issues to aid in debugging. + +TODO: Add specific examples of CBOR-encoded DIDComm messages in the appendix. diff --git a/docs/spec-files/message_structure.md b/docs/spec-files/message_structure.md index 9e55899..d930fb7 100644 --- a/docs/spec-files/message_structure.md +++ b/docs/spec-files/message_structure.md @@ -8,19 +8,19 @@ This specification discusses messages in three different formats. The casual phr Circumstances sometimes require communication about the format of DIDComm messages. The canonical way to do this is with IANA media types, based on the conventions of [RFC6838](https://tools.ietf.org/html/rfc6838). -All three DIDComm message formats — plaintext, signed, and encrypted — can be correctly understood as more generic [JWMs (JSON Web Messages)](https://tools.ietf.org/html/draft-looker-jwm-01) or even as arbitrary JOSE content. Since code that expects JOSE conventions but not DIDComm may matter in some implementations, this spec recommends the JOSE convention of [using `typ` to make JOSE structure formats self-describing](https://tools.ietf.org/html/rfc7515#section-4.1.9). This is particularly helpful in the outermost envelope of any DIDComm message, before unwrapping begins. (As RFC 7515 notes, `typ` "will typically not be used by applications when the kind of object is already known.") +All three DIDComm message formats — plaintext, signed, and encrypted — can be correctly understood as more generic [JWMs (JSON Web Messages)](https://tools.ietf.org/html/draft-looker-jwm-01) or the equivilent CBOR encoding. Since code that expects JOSE/COSE conventions but not DIDComm may matter in some implementations, this spec recommends the convention of [using `typ` to make structure formats self-describing](https://tools.ietf.org/html/rfc7515#section-4.1.9). This is particularly helpful in the outermost envelope of any DIDComm message, before unwrapping begins. (As RFC 7515 notes, `typ` "will typically not be used by applications when the kind of object is already known.") When a sender prepares a message for [routing](#routing-protocol-20), it wraps the message once for each hop that has cryptographic consequences in the path. Each wrapping operation applies one or more layers of envelope, and potentially transforms the associated media type of the output. The relevant possibilities are: -| Envelopes | IANA type (`typ` header) | Notes -|-----------------|-------|----| -| plaintext (no envelope) | `application/didcomm-plain+json`| Used as the building block of [higher-level protocols](#protocols), but rarely transmitted directly, since it lacks security guarantees. -| signed(plaintext) | `application/didcomm-signed+json` | Adds non-repudiation to a plaintext message; whoever receives a message wrapped in this way can prove its origin to any external party. -| anoncrypt(plaintext) | `application/didcomm-encrypted+json` | Guarantees confidentiality and integrity without revealing the identity of the sender. -| authcrypt(plaintext) | `application/didcomm-encrypted+json` | Guarantees confidentiality and integrity. Also proves the identity of the sender -- but in a way that only the recipient can verify. This is the default wrapping choice, and SHOULD be used unless a different goal is clearly identified. By design, this combination and all other combinations that use encryption in their outermost layer share an identical IANA media type, because only the recipient should care about the difference. -| anoncrypt(sign(plaintext)) | `application/didcomm-encrypted+json`| Guarantees confidentiality, integrity, and non-repudiation -- but prevents an observer of the outer envelope from accessing the signature. Relative to authcrypt(plaintext), this increases guarantees to the recipient, since non-repudiation is stronger than simple authentication. However, it also forces the sender to talk "on the record" and is thus not assumed to be desirable by default. -| authcrypt(sign(plaintext)) | `application/didcomm-encrypted+json` | Adds no useful guarantees over the previous choice, and is slightly more expensive, so this wrapping combination SHOULD NOT be emitted by conforming implementations. However, implementations MAY accept it. If they choose to do so, they MUST emit an error if the signer of the plaintext is different from the sender identified by the authcrypt layer. -| anoncrypt(authcrypt(plaintext)) | `application/didcomm-encrypted+json` | A specialized combination that hides the `skid` header in the authcrypt envelope, so the hop immediately sourceward of a mediator cannot discover an identifier for the sender. See [Protecting the Sender Identity](#protecting-the-sender-identity). +| Envelopes | IANA type (`typ` header) for JSON | IANA type (`typ` header) for CBOR | Notes +|-----------------|-------|-------|---| +| plaintext (no envelope) | `application/didcomm-plain+json`| `application/didcomm-plain+cbor` | Used as the building block of [higher-level protocols](#protocols), but rarely transmitted directly, since it lacks security guarantees. +| signed(plaintext) | `application/didcomm-signed+json` | `application/didcomm-signed+cbor` | Adds non-repudiation to a plaintext message; whoever receives a message wrapped in this way can prove its origin to any external party. +| anoncrypt(plaintext) | `application/didcomm-encrypted+json` | `application/didcomm-encrypted+cbor` | Guarantees confidentiality and integrity without revealing the identity of the sender. +| authcrypt(plaintext) | `application/didcomm-encrypted+json` | `application/didcomm-encrypted+cbor` | Guarantees confidentiality and integrity. Also proves the identity of the sender -- but in a way that only the recipient can verify. This is the default wrapping choice, and SHOULD be used unless a different goal is clearly identified. By design, this combination and all other combinations that use encryption in their outermost layer share an identical IANA media type, because only the recipient should care about the difference. +| anoncrypt(sign(plaintext)) | `application/didcomm-encrypted+json`| `application/didcomm-encrypted+cbor` | Guarantees confidentiality, integrity, and non-repudiation -- but prevents an observer of the outer envelope from accessing the signature. Relative to authcrypt(plaintext), this increases guarantees to the recipient, since non-repudiation is stronger than simple authentication. However, it also forces the sender to talk "on the record" and is thus not assumed to be desirable by default. +| authcrypt(sign(plaintext)) | `application/didcomm-encrypted+json` | `application/didcomm-encrypted+cbor` | Adds no useful guarantees over the previous choice, and is slightly more expensive, so this wrapping combination SHOULD NOT be emitted by conforming implementations. However, implementations MAY accept it. If they choose to do so, they MUST emit an error if the signer of the plaintext is different from the sender identified by the authcrypt layer. +| anoncrypt(authcrypt(plaintext)) | `application/didcomm-encrypted+json` | `application/didcomm-encrypted+cbor` | A specialized combination that hides the `skid` header in the authcrypt envelope, so the hop immediately sourceward of a mediator cannot discover an identifier for the sender. See [Protecting the Sender Identity](#protecting-the-sender-identity). In the aggregate, complex combinations of envelopes may occur across a route. However, in the set of envelopes that targets a single hop, envelope combinations other than the ones above MUST NOT be used. In particular, it makes no sense to use anoncrypt(authcrypt(sign(plaintext))); use anoncrypt(sign(plaintext)) instead. @@ -34,11 +34,11 @@ When higher-level protocols are built atop DIDComm Messaging, applications remov In isolation, plaintext messages lack confidentiality and integrity guarantees, and are repudiable. They are therefore not normally transported across security boundaries. However, this may be a helpful format to inspect in debuggers, since it exposes underlying semantics, and it is the format used in this specification to give examples of headers and other internals. Depending on ambient security, plaintext may or may not be an appropriate format for DIDComm Messaging data at rest. -The media type for a generic DIDComm plaintext message MUST be reported as `application/didcomm-plain+json` by conformant implementations. +The media type for a generic DIDComm plaintext message MUST be reported as `application/didcomm-plain+json` for JSON encoding or `application/didcomm-plain+cbor` for CBOR encoding by conformant implementations. The media type of the envelope MAY be set in the [`typ` property](https://tools.ietf.org/html/rfc7515#section-4.1.9) of the plaintext; it SHOULD be set if the message is intended for use without a signature or encryption. -When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm plaintext messages SHOULD be `dcpm`, giving a globbing pattern of `*.dcpm`; this SHOULD be read as "Star Dot D C P M" or as "D C P M" files. We imagine people will reference this media type by saying, "I am looking at a DIDComm Plaintext Message file", or "This database record is in DIDComm Plaintext format", or "Does my editor have a DIDComm Plaintext Message plugin?" A possible icon for this file format depicts green JSON text in a message bubble ([svg](../collateral/dcpm.svg) | [256x256](../collateral/dcpm-256.png) | [128x128](../collateral/dcpm-128.png) | [64x64](../collateral/dcpm-64.png)): +When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm plaintext messages SHOULD be `dcpm` for JSON-encoded messages or `dcpm-cbor` for CBOR-encoded messages, giving a globbing pattern of `*.dcpm` or `*.dcpm-cbor`; these SHOULD be read as "Star Dot D C P M" or "Star Dot D C P M dash C B O R" files. We imagine people will reference these media types by saying, "I am looking at a DIDComm Plaintext Message file", or "This database record is in DIDComm Plaintext format", or "Does my editor have a DIDComm Plaintext Message plugin?" A possible icon for the JSON format depicts green JSON text in a message bubble ([svg](../collateral/dcpm.svg) | [256x256](../collateral/dcpm-256.png) | [128x128](../collateral/dcpm-128.png) | [64x64](../collateral/dcpm-64.png)): ![DIDComm Plaintext Message Icon](../collateral/dcpm-128.png) @@ -50,39 +50,37 @@ Signed messages are not necessary to provide message integrity (tamper evidence) When a message is *both* signed and encrypted, this spec echoes the [JOSE recommendation about how to combine](https://datatracker.ietf.org/doc/html/rfc7519#section-11.2): sign the plaintext first, and then encrypt. (The opposite order would imply that the signer committed to opaque data. This would be less safe, and would undermine non-repudiation.) -The [media type](https://tools.ietf.org/html/rfc6838) of a DIDComm signed message MUST be `application/didcomm-signed+json`. +The [media type](https://tools.ietf.org/html/rfc6838) of a DIDComm signed message MUST be `application/didcomm-signed+json` for JSON encoding or `application/didcomm-signed+cbor` for CBOR encoding. -The media type of the envelope SHOULD be set in the [`typ` property](https://tools.ietf.org/html/rfc7515#section-4.1.9) of the JWS. +The media type of the envelope SHOULD be set in the [`typ` property](https://tools.ietf.org/html/rfc7515#section-4.1.9) of the JWS for JSON encoding, or in the equivalent header parameter for COSE Sign1 or COSE Sign for CBOR encoding. -In order to avoid [surreptitious forwarding or malicious usage](https://theworld.com/~dtd/sign_encrypt/sign_encrypt7.html) of a signed message, a signed message SHOULD contain a properly defined `to` header. In the case where a message is *both* signed and encrypted, the inner (signed) JWM being signed MUST contain a `to` header. +In order to avoid [surreptitious forwarding or malicious usage](https://theworld.com/~dtd/sign_encrypt/sign_encrypt7.html) of a signed message, a signed message SHOULD contain a properly defined `to` header. In the case where a message is *both* signed and encrypted, the inner (signed) message being signed MUST contain a `to` header. -When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm signed messages SHOULD be `dcsm`, giving a globbing pattern of `*.dcsm`; this SHOULD be be read as "Star Dot D C S M" or as "D C S M" files. A possible icon for this media type depicts a signed envelope ([svg](../collateral/dcsm.svg) | [256x256](../collateral/dcsm-256.png) | [128x128](../collateral/dcsm-128.png) | [64x64](../collateral/dcsm-64.png)): +When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm signed messages SHOULD be `dcsm` for JSON-encoded messages or `dcsm-cbor` for CBOR-encoded messages, giving a globbing pattern of `*.dcsm` or `*.dcsm-cbor`; these SHOULD be read as "Star Dot D C S M" or "Star Dot D C S M dash C B O R" files. A possible icon for the JSON format depicts a signed envelope ([svg](../collateral/dcsm.svg) | [256x256](../collateral/dcsm-256.png) | [128x128](../collateral/dcsm-128.png) | [64x64](../collateral/dcsm-64.png)): ![DIDComm Signed Message Icon](../collateral/dcsm-128.png) ### DIDComm Encrypted Messages -A **DIDComm encrypted message** is an encrypted [JWM](https://tools.ietf.org/html/draft-looker-jwm-01). It hides its content from all but authorized recipients, discloses and proves the sender to exactly and only those recipients, and provides integrity guarantees. It is important in privacy-preserving routing. It is what normally moves over network transports in DIDComm Messaging applications, and is the safest format for storing DIDComm Messaging data at rest. +A **DIDComm encrypted message** is an encrypted message. When using JSON encoding, it is an encrypted [JWM](https://tools.ietf.org/html/draft-looker-jwm-01) using JWE. When using CBOR encoding, it uses COSE Encrypt or COSE Encrypt0. It hides its content from all but authorized recipients, discloses and proves the sender to exactly and only those recipients, and provides integrity guarantees. It is important in privacy-preserving routing. It is what normally moves over network transports in DIDComm Messaging applications, and is the safest format for storing DIDComm Messaging data at rest. -The [media type](https://tools.ietf.org/html/rfc6838) of a non-nested DIDComm encrypted message MUST be `application/didcomm-encrypted+json`. +The [media type](https://tools.ietf.org/html/rfc6838) of a non-nested DIDComm encrypted message MUST be `application/didcomm-encrypted+json` for JSON encoding or `application/didcomm-encrypted+cbor` for CBOR encoding. -> Note: If future versions of this spec allow binary encodings, variations like `application/didcomm-encrypted+cbor` (see [CBOR RFC 7049, section 7.5](https://tools.ietf.org/html/rfc7049#section-7.5)), `application/didcomm-encrypted+msgpack`, or `application/didcomm-encrypted+protobuf` may become reasonable. In the future, specifications that encompass communications patterns other than messaging — DIDComm Multicast or DIDComm Streaming, for example — might use a suffix: `application/didcomm-encrypted-multicast` or similar. +The media type of the envelope SHOULD be set in the [`typ` property](https://tools.ietf.org/html/rfc7516#section-4.1.11) of the JWE for JSON encoding, or in the equivalent header parameter for COSE Encrypt or COSE Encrypt0 for CBOR encoding. -The media type of the envelope SHOULD be set in the [`typ` property](https://tools.ietf.org/html/rfc7516#section-4.1.11) of the JWE. - -When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm encrypted messages SHOULD be `dcem`, giving a globbing pattern of `*.dcem`; this SHOULD be read as "Star Dot D C E M" or as "D C E M" files. A possible icon for this file format depicts an envelope with binary overlay, protected by a lock ([svg](../collateral/dcem.svg) | [256x256](../collateral/dcem-256.png) | [128x128](../collateral/dcem-128.png) | [64x64](../collateral/dcem-64.png)): +When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm encrypted messages SHOULD be `dcem` for JSON-encoded messages or `dcem-cbor` for CBOR-encoded messages, giving a globbing pattern of `*.dcem` or `*.dcem-cbor`; these SHOULD be read as "Star Dot D C E M" or "Star Dot D C E M dash C B O R" files. A possible icon for the JSON format depicts an envelope with binary overlay, protected by a lock ([svg](../collateral/dcem.svg) | [256x256](../collateral/dcem-256.png) | [128x128](../collateral/dcem-128.png) | [64x64](../collateral/dcem-64.png)): ![DIDComm Encrypted Message Icon](../collateral/dcem-128.png) ## Plaintext Message Structure -As mentioned above, **DIDComm plaintext messages** are based on [JWM](https://tools.ietf.org/html/draft-looker-jwm-01). JWMs follow the same general pattern as other JOSE containers, but are optimized for larger and more arbitrary structure than simple tokens. +As mentioned above, **DIDComm plaintext messages** are based on [JWM](https://tools.ietf.org/html/draft-looker-jwm-01) when using JSON encoding, or on a CBOR mapping of the same structure when using CBOR encoding. JWMs follow the same general pattern as other JOSE containers, but are optimized for larger and more arbitrary structure than simple tokens. -A plaintext message has an outermost attribute, `type`, that identifies the *application-level* message category to which it belongs. This value of `type` is a [specialized URI](#message-type-uri); it allows messages to be mapped to specific handler code. Other outermost attributes include a message's `id` and its media type (`typ` attribute, for generic JWM handling, as described above). In addition, plaintext messages may have other attributes that have meaning across many message types. Such attributes at the top level of a message are called *[headers](#message-headers)*. +A plaintext message has an outermost attribute, `type`, that identifies the *application-level* message category to which it belongs. This value of `type` is a [specialized URI](#message-type-uri); it allows messages to be mapped to specific handler code. Other outermost attributes include a message's `id` and its media type (`typ` attribute, for generic message handling, as described above). In addition, plaintext messages may have other attributes that have meaning across many message types. Such attributes at the top level of a message are called *[headers](#message-headers)*. A plaintext message also includes attributes and data specific to its message type. These are contained within its `body` attribute. -Prior to being sent, plaintext is usually encrypted into a JWE according to the [JWM](https://tools.ietf.org/html/draft-looker-jwm-01) specification. +Prior to being sent, plaintext is usually encrypted into a JWE according to the [JWM](https://tools.ietf.org/html/draft-looker-jwm-01) specification when using JSON encoding, or into a COSE Encrypt or COSE Encrypt0 structure when using CBOR encoding. The following example shows common elements of a DIDComm plaintext message. @@ -101,6 +99,17 @@ The following example shows common elements of a DIDComm plaintext message. } ``` +The equivalent CBOR encoding would represent the same data structure but in the more compact CBOR binary format. The CBOR map would use the same keys and value types as the JSON structure. + +## Encoding Detection +As messages may be both JSON or CBOR encoded. The encoding of the message can be determined by inspection of the first byte as follows: + +JSON messages MUST begin with a first byte of `0x7B` ASCII `{`. + +CBOR messages MUST begin with a first byte value between `0x80` and `0xFF`. + +Other first byte values are not valid at this time. + ### Message Headers A DIDComm plaintext message conveys most of its application-level data inside a JSON `body` object that is a direct child of the message root. The structure inside `body` is predicted by the value of the message's `type` attribute, and varies according to the definition of the protocol-specific message in question. Each `type` of message has its own schema for `body`. @@ -178,7 +187,7 @@ Each attachment is described with an instance of a JSON object that has the foll - `format` - OPTIONAL. Further describes the format of the attachment if the `media_type` is not sufficient. - `lastmod_time` - OPTIONAL. A hint about when the content in this attachment was last modified. - `data`: A JSON object that gives access to the actual content of the attachment. This MUST contain at least one of the following subfields, and enough of them to allow access to the data: - * `jws` - OPTIONAL. A [JWS](https://tools.ietf.org/html/rfc7515) in [detached content mode](https://tools.ietf.org/html/rfc7515#appendix-F), where the `payload` field of the JWS maps to `base64` or to something fetchable via `links`. This allows attachments to be signed. The signature need not come from the author of the message. + * `jws` - OPTIONAL. A [JWS](https://tools.ietf.org/html/rfc7515) in [detached content mode](https://tools.ietf.org/html/rfc7515#appendix-F) for JSON encoding, or a COSE Sign1 or COSE Sign structure in detached content mode for CBOR encoding, where the payload field maps to `base64` or to something fetchable via `links`. This allows attachments to be signed. The signature need not come from the author of the message. * `hash` - OPTIONAL. The hash of the content encoded in multi-hash format. Used as an integrity check for the attachment, and MUST be used if the data is referenced via the `links` data attribute. * `links` - OPTIONAL. A list of zero or more locations at which the content may be fetched. This allows content to be attached by reference instead of by value. * `base64` - OPTIONAL. [Base64url](https://tools.ietf.org/html/rfc4648#section-5)-encoded data, when representing arbitrary content inline instead of via `links`. @@ -222,7 +231,7 @@ Each attachment is described with an instance of a JSON object that has the foll { "id": "x", "description": "example encrypted DIDComm message as attachment", - "media_type": "application/didcomm-encrypted+json", + "media_type": "application/didcomm-encrypted+json", // or "application/didcomm-encrypted+cbor" for CBOR encoding "data": { "json": { //jwe json structure diff --git a/docs/spec-files/profiles.md b/docs/spec-files/profiles.md index 40a3341..d8e5f7d 100644 --- a/docs/spec-files/profiles.md +++ b/docs/spec-files/profiles.md @@ -17,6 +17,7 @@ Although DIDComm allows flexibility in each of these choices, it is not expected * `didcomm/aip2;env=rfc19`: The signing mechanism, plaintext conventions, and routing algorithms embodied in [Aries AIP 2.0](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0302-aries-interop-profile/README.md#aries-interop-profile-version-20), circa 2021 — with the old-style encryption envelope from [Aries RFC 0019](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0019-encryption-envelope#aries-rfc-0019-encryption-envelope). This legal variant of AIP 2.0 minimizes differences with codebases that shipped AIP 1.0 support. * `didcomm/aip2;env=rfc587`: The signing mechanism, plaintext conventions, and routing algorithms embodied in [Aries AIP 2.0](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0302-aries-interop-profile/README.md#aries-interop-profile-version-20), circa 2021 — with the new-style encryption envelope from [Aries RFC 0587](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0587-encryption-envelope-v2). This legal variant of AIP 2.0 lays the foundation for DIDComm v2 support by anticipating the eventual envelope change. * `didcomm/v2`: The encryption envelope, signing mechanism, plaintext conventions, and routing algorithms embodied in this spec. +* `didcomm/v2+cbor`: The encryption envelope, signing mechanism, plaintext conventions, and routing algorithms embodied in this spec, but encoded in the optional CBOR format as a replacent for JSON. Profiles are named in the `accept` section of a [DIDComm service endpoint](#service-endpoint) and in an [out-of-band message](#out-of-band-messages). When Alice declares that she accepts `didcomm/v2`, she is making a declaration about more than her own endpoint. She is saying that all publicly visible steps in an inbound route to her will use the `didcomm/v2` profile, such that a sender only has to use `didcomm/v2` choices to get the message from Alice's outermost mediator to Alice's edge. It is up to Alice to select and configure [mediators](#roles) and internal routing in such a way that this is true for the sender. diff --git a/docs/spec-files/routing.md b/docs/spec-files/routing.md index e37353e..c3c24ff 100644 --- a/docs/spec-files/routing.md +++ b/docs/spec-files/routing.md @@ -127,6 +127,7 @@ The relevant entry in the DID document matches one of the following formats: "uri": "https://example.com/path", "accept": [ "didcomm/v2", + "didcomm/v2+cbor", "didcomm/aip2;env=rfc587" ], "routingKeys": ["did:example:somemediator#somekey"]