RFC 9202

Datagram Transport Layer Security (DTLS) Profile for Authentication and Authorization for Constrained Environments (ACE)

๐Ÿ“… published August 2022, from ietf

Part 1 of 6 โœจ

RFC 9202: DTLS Profile for ACE ๐ŸŽ€

okay bestie, this is RFC 9202, titled Datagram Transport Layer Security (DTLS) Profile for Authentication and Authorization for Constrained Environments (ACE) ๐Ÿ’–

  • Authors: S. Gerdes, O. Bergmann, C. Bormann (Universitรคt Bremen TZI), G. Selander (Ericsson AB), and L. Seitz (Combitech) ๐Ÿซถ
  • Category: Standards Track ๐Ÿ‘‘
  • Date: August 2022 ๐Ÿ“…
  • ISSN: 2070-1721
  • Obsoletes / Updates: the header doesn't list anything it obsoletes or updates, so this one's a standalone spec ๐Ÿฆ‹

Abstract โœจ

so this spec is a profile of the ACE framework that lets constrained servers hand off client authentication and authorization to someone else ๐Ÿ”. it relies on DTLS version 1.2 or later for communication security inside a constrained network, and it works with either raw public keys or pre-shared keys ๐Ÿ—๏ธ. a resource-constrained server can delegate managing its authorization information to a trusted host that has less-severe limits on processing power and memory ๐Ÿ’ช๐ŸŒธ

Status of This Memo ๐Ÿ“œ

this is an Internet Standards Track document ๐ŸŽ€

it's a product of the Internet Engineering Task Force (IETF), it represents the consensus of the IETF community, it got public review, and the Internet Engineering Steering Group (IESG) approved it for publication ๐Ÿซถ for more on Internet Standards, check Section 2 of RFC 7841 ๐Ÿ’…

info about the current status, errata, and how to send feedback lives at https://www.rfc-editor.org/info/rfc9202 ๐ŸŒˆ

Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿ’œ

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the publication date. please actually read those, bestie, because they spell out your rights and restrictions for this document ๐Ÿ™ˆ

if you extract Code Components from this document, they must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions. they're also provided without warranty, as described in the Revised BSD License. โš ๏ธ

Table of Contents ๐Ÿงš

   1.  Introduction
     1.1.  Terminology
   2.  Protocol Overview
   3.  Protocol Flow
     3.1.  Communication between the Client and the Authorization
           Server
     3.2.  Raw Public Key Mode
       3.2.1.  Access Token Retrieval from the Authorization Server
       3.2.2.  DTLS Channel Setup between the Client and Resource
               Server
     3.3.  Pre-shared Key Mode
       3.3.1.  Access Token Retrieval from the Authorization Server
       3.3.2.  DTLS Channel Setup between the Client and Resource
               Server
     3.4.  Resource Access
   4.  Dynamic Update of Authorization Information
   5.  Token Expiration
   6.  Secure Communication with an Authorization Server
   7.  Security Considerations
     7.1.  Reuse of Existing Sessions
     7.2.  Multiple Access Tokens
     7.3.  Out-of-Band Configuration
   8.  Privacy Considerations
   9.  IANA Considerations
   10. References
     10.1.  Normative References
     10.2.  Informative References
   Acknowledgments
   Authors' Addresses

1. Introduction ๐ŸŒธ

okay so this spec defines a profile of the ACE framework [RFC9200] ๐Ÿ’… in this profile, a client (C) and a resource server (RS) talk using the Constrained Application Protocol (CoAP) [RFC7252] over DTLS version 1.2 [RFC6347]. this spec uses DTLS 1.2 terminology, but later versions like DTLS 1.3 [RFC9147] can be used instead โœจ

the client gets an access token from an authorization server (AS) to prove it's allowed to access protected resources on the resource server. that token is bound to a key, called the proof-of-possession (PoP) key ๐Ÿ”‘ the AS also gives the client and the resource server the keying material they need to set up a DTLS session ๐Ÿซถ the client and the AS can also secure their communication with DTLS ๐Ÿ”

this spec supports DTLS with raw public keys (RPKs) [RFC7250] and with pre-shared keys (PSKs) [RFC4279]. token introspection [RFC7662] between the RS and AS is out of scope here, so it's not covered ๐Ÿ™ˆ

the ACE framework needs the client and server to mutually authenticate each other before any application data gets exchanged ๐Ÿ’– DTLS makes mutual authentication possible when both sides prove they can use certain keying material during the DTLS handshake ๐Ÿค on the server side, the AS helps by putting keying material (or info about keying material) into the access token, which counts as a proof-of-possession token ๐Ÿงš

in RPK mode, the client proves it can use the RPK bound to the token, and the server shows that it can use a certain RPK ๐Ÿฆ‹

the resource server needs access to the token to finish this exchange. for RPK mode, the client has to upload the access token to the resource server before starting the handshake, as described in Section 5.10.1 of the ACE framework [RFC9200] ๐Ÿ“ค

in PSK mode, the client and server show during the DTLS handshake that they can use the keying material bound to the access token ๐Ÿ—๏ธ to get the access token from the client to the resource server, the psk_identity parameter in the DTLS PSK handshake can be used instead of uploading the token before the handshake ๐ŸŽ€

as recommended in Section 5.8 of [RFC9200], this spec uses CBOR web tokens (Concise Binary Object Representation) to carry claims inside an access token issued by the server ๐Ÿ“ other formats could work too, but they're out of scope for this document ๐Ÿ™…โ€โ™€๏ธ

1.1. Terminology ๐Ÿ“–

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here ๐Ÿซถ these capitalized words are the ones with real force, so lowercase versions don't count ๐Ÿ‘‘

you're expected to already know the terms and concepts in [RFC9200] and [RFC9201] ๐Ÿง 

the authorization information (authz-info) resource is the authorization information endpoint from [RFC9200] ๐Ÿ’… the word claim means the same thing here as it does in [RFC9200], i.e., information carried in the access token or returned from introspection ๐ŸŒˆ

across this doc, CBOR data item examples are written in CBOR extended diagnostic notation, as defined in Section 8 of [RFC8949] and Appendix G of [RFC8610] ("diagnostic notation"), unless noted otherwise ๐Ÿฆ‹ we often add diagnostic notation comments to give a text version of the numeric parameter names and values ๐Ÿ”ข

2. Protocol Overview โœจ

the CoAP-DTLS profile for ACE handles two things: transferring authentication information and, if needed, authorization information between the client (C) and the resource server (RS) while setting up a DTLS session for CoAP messaging ๐Ÿ’– it also explains how the client can use CoAP over DTLS to get an access token from the authorization server (AS) for a protected resource on the resource server ๐Ÿซถ as Section 6.7 of [RFC9200] says, using DTLS for one or both of these interactions is completely independent ๐ŸŒธ

this profile requires the client to get an access token for the protected resource(s) it wants on the resource server, as specified in [RFC9200] ๐ŸŽŸ๏ธ Figure 1 shows the typical message flow here (messages in square brackets are optional) ๐Ÿ‘‡

      C                                RS                   AS
      | [---- Resource Request ------>]|                     |
      |                                |                     |
      | [<-AS Request Creation Hints-] |                     |
      |                                |                     |
      | ------- Token Request  ----------------------------> |
      |                                |                     |
      | <---------------------------- Access Token --------- |
      |                               + Access Information   |

                    Figure 1: Retrieving an Access Token

so how does the client figure out which authorization server handles a resource on the resource server? easy ๐Ÿงš it sends an initial Unauthorized Resource Request message to the resource server. the RS denies the request and sends back an AS Request Creation Hints message with its authorization server's address, as Section 5.3 of [RFC9200] describes ๐Ÿ”

once the client knows the AS address, it can send an access token request to the token endpoint at that AS, as specified in [RFC9200] ๐ŸŽ€ the access token request and response might carry confidential data, so the communication between the client and the authorization server must be confidentiality protected and ensure authenticity ๐Ÿ” the client is expected to have been registered at the authorization server, as outlined in Section 4 of [RFC9200] ๐Ÿ“

the AS's access token can then be used by the client to set up a new DTLS session with the resource server ๐Ÿฆ‹ if the client plans to use an asymmetric proof-of-possession key in the DTLS handshake with the RS, the client MUST upload the access token to the authz-info resource (the authz-info endpoint) on the resource server before starting the DTLS handshake, as described in Section 5.10.1 of [RFC9200] ๐Ÿ“ค if the client uses a symmetric proof-of-possession key in the DTLS handshake, the procedure above MAY be used, or the access token MAY instead be transferred in the DTLS ClientKeyExchange message (see Section 3.3.2) ๐Ÿ—๏ธ in any case, DTLS MUST be used in a mode that provides replay protection ๐Ÿ›ก๏ธ

no matter which key type you pick, DTLS MUST be used in a mode that provides replay protection. non-negotiable, bestie ๐Ÿ’€

Figure 2 shows the common protocol flow for the DTLS profile after the client has gotten the access token from the authorization server (AS) ๐ŸŒˆ

      C                            RS                   AS
      | [--- Access Token ------>] |                     |
      |                            |                     |
      | <== DTLS channel setup ==> |                     |
      |                            |                     |
      | == Authorized Request ===> |                     |
      |                            |                     |
      | <=== Protected Resource == |                     |

                        Figure 2: Protocol Overview

3. Protocol Flow โœจ

okay so this section is where the magic happens ๐Ÿฆ‹ CoAP gets used to pass access-related data between the resource server, the client, and the authorization server. the goal is that the authorization server gives the client and the resource server enough info to set up a secure channel, and also sends along the authorization info for this specific relationship to the resource server. ICONIC teamwork ๐Ÿซถ

Section 3.1 covers how the client (C) and the authorization server (AS) have to secure their talk. depending on which CoAP security mode you're using (see also Section 9 of [RFC7252]), the client-to-AS request, the AS-to-client response, and the DTLS session setup all carry slightly different info ๐Ÿ’… Section 3.2 is about raw public keys, and Section 3.3 explains how pre-shared keys work in this profile ๐Ÿ”‘

3.1. Communication between the Client and the Authorization Server ๐Ÿ”

so the client wants an access token for a resource, right? it asks the authorization server for one. BUT before the client can even ask, the client and the authorization server MUST set up a secure channel first ๐Ÿ›ก๏ธ this profile assumes the keying material for that channel was obtained securely, either by manual configuration or through an automated provisioning process. the following requirements line up with Section 6.5 of [RFC9200], so they therefore must be met:

  • The client MUST securely have obtained keying material to communicate with the authorization server.
  • Furthermore, the client MUST verify that the authorization server is authorized to provide access tokens (including authorization information) about the resource server to the client, and that this authorization information about the authorization server is still valid. main character energy for verifying things ๐Ÿ‘‘
  • Also, the authorization server MUST securely have obtained keying material for the client, and it MUST have obtained authorization rules approved by the resource owner (RO) concerning the client and the resource server that relate to this keying material.

the client and the authorization server MUST use their own keying material for all exchanged messages. how the security association between them gets bootstrapped is NOT part of this document (not our problem, bestie ๐Ÿ™ˆ). the client and the authorization server must ensure the confidentiality, integrity, and authenticity of all exchanged messages within the ACE protocol ๐Ÿ“

Section 6 specifies how communication with the authorization server is secured ๐ŸŒธ

3.2. Raw Public Key Mode ๐ŸŽ€

when the client uses raw public key authentication, the procedure goes like this โœจ

3.2.1. Access Token Retrieval from the Authorization Server ๐Ÿงš

so after the client and the authorization server have mutually authenticated each other and validated each other's authorization, the client sends a token request to the authorization server's token endpoint ๐Ÿ“ฎ the client MUST add a req_cnf object carrying either its raw public key, or a unique identifier for a public key it has already made known to the authorization server. it is RECOMMENDED that the client uses DTLS with the same keying material to secure the communication with the authorization server, which also proves possession of the key as part of the token request. other ways of proving possession of the key MAY be defined in the future ๐Ÿ”ฎ

here's an example access token request from the client to the authorization server, shown in Figure 3 ๐Ÿ’–

   POST coaps://as.example.com/token
   Content-Format: application/ace+cbor
   Payload:
   {
     / grant_type / 33 : / client_credentials / 2,
     / audience /    5 : "tempSensor4711",
     / req_cnf /     4 : {
       / COSE_Key / 1 : {
         / kty /  1 : / EC2 /   2,
         / crv / -1 : / P-256 / 1,
         / x /   -2 : h'e866c35f4c3c81bb96a1/.../',
         / y /   -3 : h'2e25556be097c8778a20/.../'
       }
     }
   }

         Figure 3: Access Token Request Example for RPK Mode

this example asks for the resource called "tempSensor4711" on the authorization server, using a raw public key ๐ŸŒˆ

the authorization server MUST check that the client it's talking to is associated with the RPK in the req_cnf parameter BEFORE it issues an access token. if the authorization server decides the request should be authorized according to the respective authorization rules, it generates an access token response for the client โœ… the access token MUST be bound to the client's RPK by means of the cnf claim ๐Ÿ”’

the response MUST contain an ace_profile parameter if the ace_profile parameter in the request is empty, and MAY contain it otherwise (see Section 5.8.2 of [RFC9200]). this parameter is set to coap_dtls to indicate that this profile MUST be used for communication between the client and the resource server ๐Ÿ’… the response also carries an access token with info for the resource server about the client's public key. the authorization server MUST return the rs_cnf parameter in its response UNLESS it is certain that the client already knows the resource server's public key ๐Ÿซฃ the authorization server MUST make sure the RPK in rs_cnf belongs to the resource server the client wants to talk to. the authorization server MUST protect the integrity of the access token so the resource server can detect unauthorized changes, and if the access token has confidential data, the authorization server MUST also protect its confidentiality ๐Ÿ›ก๏ธ

the client MUST make sure the access token response belongs to a certain, previously sent access token request, because the request may specify which resource server the client wants to talk to ๐Ÿง

here's an example access token response from the authorization server to the client, shown in Figure 4. the contents of the access_token claim have been truncated to keep it readable ๐Ÿ“– for the client, the response includes Access Information containing the server's public key in the rs_cnf parameter. caching proxies process the Max-Age option in the CoAP response, which has a default value of 60 seconds (Section 5.6.1 of [RFC7252]). the authorization server SHOULD adjust the Max-Age option so it does not exceed the expires_in parameter, which helps avoid stale responses ๐Ÿ™ƒ

   2.01 Created
   Content-Format: application/ace+cbor
   Max-Age: 3560
   Payload:
   {
     / access_token / 1 : b64'SlAV32hk'/...
      (remainder of CWT omitted for brevity;
      CWT contains the client's RPK in the cnf claim)/,
     / expires_in /  2 : 3600,
     / rs_cnf /     41 : {
       / COSE_Key /  1 : {
         / kty /  1 : / EC2 /   2,
         / crv / -1 : / P-256 / 1,
         / x /   -2 : h'd7cc072de2205bdc1537/.../',
         / y /   -3 : h'f95e1d4b851a2cc80fff/.../'
       }
     }
   }

         Figure 4: Access Token Response Example for RPK Mode

3.2.2. DTLS Channel Setup between the Client and Resource Server ๐Ÿฆ‹

before the client starts the DTLS handshake with the resource server, the client MUST send a POST request containing the access token it got to the authz-info resource hosted by the resource server ๐Ÿ“ฌ once the client gets confirmation that the resource server accepted the access token, it moves on and sets up a new DTLS channel with the resource server ๐Ÿš€ the client MUST use its correct public key in the DTLS handshake. if the authorization server specified a cnf field in the access token response, the client MUST use that key. otherwise, the client MUST use the public key it specified in the req_cnf of the access token request. the client MUST put this public key in the SubjectPublicKeyInfo structure of the DTLS handshake, as described in [RFC7250] ๐Ÿ”‘

if the client doesn't have the keying material belonging to the public key, the client MAY try sending an access token request to the AS, where it specifies its public key in the req_cnf parameter ๐Ÿ™ if the AS still gives back a public key the client doesn't have, the client SHOULD re-register with the authorization server to establish a new client public key. this process is out of scope for this document ๐Ÿ™ˆ

to be consistent with [RFC7252], which allows shortened Message Authentication Code (MAC) tags in constrained environments, an implementation that supports the RPK mode of this profile MUST at least support the cipher suite TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 [RFC7251] ๐Ÿง as discussed in [RFC7748], newer Elliptic Curve Cryptography (ECC) curves have been defined recently that are considered superior to the so-called NIST curves ๐ŸŒŸ so implementations of this profile MUST implement support for curve25519 (cf. [RFC8032], [RFC8422]). this curve is said to be efficient and less dangerous, when it comes to implementation errors, than the secp256r1 curve mandated in [RFC7252] ๐Ÿ’œ

the resource server MUST check that the access token is still valid, that the resource server is the intended destination (i.e., the audience) of the token, and that the token was issued by an authorized authorization server (see also Section 5.10.1.1 of [RFC9200]) ๐Ÿ•ต๏ธโ€โ™€๏ธ the authorization server builds the access token so the resource server can associate it with the client's public key. the cnf claim MUST contain either the client's RPK or, if the resource server already knows the key (e.g., from previous communication), a reference to this key. if the authorization server has no certain knowledge that the client's key is already known to the resource server, the client's public key MUST be included in the access token's cnf parameter. if CBOR web tokens [RFC8392] are used (as recommended in [RFC9200]), keys MUST be encoded as specified in [RFC8747] ๐ŸŽ€ a resource server MUST have the capacity to store one access token for every proof-of-possession key of every authorized client ๐Ÿ—„๏ธ

the raw public key used in the DTLS handshake with the client MUST belong to the resource server. if the resource server has several raw public keys, it needs to figure out which one to use. the authorization server can help with this decision by including a cnf parameter in the access token that is associated with this communication. in that case, the resource server MUST use the information from the cnf field to select the proper keying material ๐ŸŽฏ

so yeah, the handshake only finishes if the client and the resource server are both able to use their respective keying material ๐Ÿคโœจ

3.3. Pre-shared Key Mode ๐Ÿ—๏ธ

when the client uses pre-shared key authentication, the procedure goes like this ๐ŸŒธ

3.3.1. Access Token Retrieval from the Authorization Server โœจ

okay so, to grab an access token for the resource the client wants to reach, the client MAY tuck a req_cnf object into its access token request to the authorization server ๐Ÿ’… Inside that object goes an identifier for a symmetric key. The authorization server uses that identifier to figure out which shared secret to use when it builds the proof-of-possession token ๐Ÿ”‘. Then the authorization server MUST check whether the identifier points to a symmetric key it already generated earlier as a shared secret for this client and resource server pair. If it can't find one, the authorization server MUST generate a brand new symmetric key and send it back in its response to the client ๐Ÿฆ‹

The authorization server MUST determine the authorization rules for the client it's talking to, as the resource owner defined them, and make the access token to match ๐Ÿ‘‘ If it authorizes the client, it returns an AS-to-client response. If the ace_profile parameter is present, it is set to coap_dtls. The authorization server MUST ascertain that the access token is generated for the resource server the client wants to talk to ๐ŸŽ€ It also MUST protect the integrity of the access token so the resource server can detect unauthorized changes. If the token contains confidential data, like the symmetric key, the confidentiality of the token MUST also be protected ๐Ÿ”

Depending on the requested token type and algorithm in the access token request, the authorization server adds Access Information to the response. This gives the client enough info to set up a DTLS channel with the resource server ๐Ÿงš The authorization server adds a cnf parameter to the Access Information, carrying a COSE_Key object that tells the client about the shared secret it should use with the resource server. To hand that same secret to the resource server, the authorization server can include it directly in the access token by means of the cnf claim, or it can provide enough information for the resource server to derive the shared secret from the access token ๐ŸŒธ As an alternative, the resource server MAY use token introspection to retrieve the keying material for this access token directly from the authorization server ๐Ÿ’œ

An example access token request for an access token with a symmetric proof-of-possession key is shown in Figure 5.

POST coaps://as.example.com/token
Content-Format: application/ace+cbor
Payload:
{
  / audience / 5 : "smokeSensor1807"
}

Figure 5: Example Access Token Request, (Implicit) Symmetric PoP Key

A matching example access token response is in Figure 6. In this one, the authorization server returns a 2.01 response with a new access token (chopped short so it's easier to read) plus info for the client, including the symmetric key in the cnf claim. The info is transferred as a CBOR data structure, as specified in [RFC9200].

2.01 Created
Content-Format: application/ace+cbor
Max-Age: 85800
Payload:
{
   / access_token /  1 : h'd08343a1/...
     (remainder of CWT omitted for brevity)/',
   / token_type /   34 : / PoP / 2,
   / expires_in /    2 : 86400,
   / ace_profile /  38 : / coap_dtls / 1,
   / cnf /           8 : {
     / COSE_Key / 1 : {
       / kty / 1 : / symmetric / 4,
       / kid / 2 : h'3d027833fc6267ce',
       / k /  -1 : h'73657373696f6e6b6579'
     }
   }
}

Figure 6: Example Access Token Response, Symmetric PoP Key

The access token also comprises a cnf claim. This claim usually contains a COSE_Key object [RFC8152] that carries either the symmetric key itself or a key identifier that the resource server can use to determine the secret key it shares with the client. If the access token carries a symmetric key, the access token MUST be encrypted using a COSE_Encrypt0 structure (see Section 7.1 of [RFC8392]). The authorization server MUST use the keying material shared with the resource server to encrypt the token.

The cnf structure in the access token is shown in Figure 7.

/ cnf / 8 : {
  / COSE_Key / 1 : {
    / kty / 1 : / symmetric / 4,
    / kid / 2 : h'3d027833fc6267ce'
  }
}

Figure 7: Access Token without Keying Material

A response that declines any operation on the requested resource is constructed according to Section 5.2 of [RFC6749] (cf. Section 5.8.3 of [RFC9200]). Figure 8 shows an example for a request that has been rejected due to invalid request parameters.

4.00 Bad Request
Content-Format: application/ace+cbor
Payload:
{
  / error / 30 : / invalid_request / 1
}

Figure 8: Example Access Token Response with Reject

The method for how the resource server determines the symmetric key from an access token containing only a key identifier is application specific. The rest of this section provides one example.

The authorization server and the resource server are assumed to share a key derivation key, which is used to derive the symmetric key shared with the client from the key identifier in the access token. The key derivation key may be derived from some other secret key shared between the authorization server and the resource server. This key needs to be securely stored and processed in the same way as the key used to protect the communication between the authorization server and the resource server.

Knowledge of the symmetric key shared with the client must not reveal any information about the key derivation key or other secret keys shared between the authorization server and resource server.

To generate a new symmetric key for the client and resource server, the authorization server generates a new key identifier that MUST be unique among all key identifiers used by the authorization server for this resource server. The authorization server then uses the key derivation key shared with the resource server to derive the symmetric key, as specified below. Instead of providing the keying material in the access token, the authorization server includes the key identifier in the kid parameter (see Figure 7). This key identifier lets the resource server calculate the symmetric key used for communication with the client, using the key derivation key and a key derivation function (KDF) to be defined by the application, for example, HKDF-SHA-256. The key identifier picked by the authorization server MUST be unique for each access token where a unique symmetric key is required.

In this example, the HMAC-based key derivation function (HKDF) consists of the composition of the HKDF-Extract and HKDF-Expand steps [RFC5869]. The symmetric key is derived from the key identifier, the key derivation key, and other data:

OKM = HKDF(salt, IKM, info, L),

where:

  • OKM, the output keying material, is the derived symmetric key
  • salt is the empty byte string
  • IKM, the input keying material, is the key derivation key, as defined above
  • info is the serialization of a CBOR array consisting of [RFC8610]:
info = [
  type : tstr,
  L    : uint,
  access_token : bytes
]

where:

  • type is set to the constant text string "ACE-CoAP-DTLS-key-derivation"
  • L is the size of the symmetric key in bytes
  • access_token is the content of the access_token field, as transferred from the authorization server to the resource server.

All CBOR data types are encoded in CBOR using preferred serialization and deterministic encoding, as specified in Section 4 of [RFC8949]. In particular, this implies that the type and L components use the minimum length encoding. The content of the access_token field is treated as opaque data for the purpose of key derivation.

Using a unique (per-resource-server) kid, and a key derivation IKM that MUST be unique per AS/RS pair as specified above, will ensure that the derived key is not shared across multiple clients. However, to provide variation in the derived key across different tokens used by the same client, it is additionally RECOMMENDED to include the iat claim and either the exp or exi claims in the access token.

3.3.2. DTLS Channel Setup between the Client and Resource Server โœจ

okay so bestie ๐ŸŽ€ when a client gets an access token response back from the authorization server, it MUST check whether that response is tied to a specific access token request it sent earlier, because that request might name the resource server the client wants to talk to ๐Ÿ’…

Then the client checks the payload for an access_token parameter and a cnf parameter ๐Ÿ‘€. With those two in hand, it can kick off a brand new DTLS channel with a resource server ๐Ÿฆ‹. For DTLS with pre-shared keys, the client follows the PSK key exchange algorithm in Section 2 of [RFC4279], and it uses the key from the cnf parameter of the AS response as the PSK when it builds the premaster secret. To stay consistent with the recommendations in [RFC7252], a client in the PSK mode MUST support the cipher suite TLS_PSK_WITH_AES_128_CCM_8 [RFC6655]. โœจ

In PreSharedKey mode, the client and the resource server both knowing the shared secret is what gives them mutual authentication ๐Ÿค. So the resource server must be able to determine the shared secret from the access token. Following the general ACE authorization framework, the client can upload the access token to the resource server's authz-info resource before it starts the DTLS handshake. Then, during the handshake, it tells the server which previously uploaded access token it wants to use. To do that, it MUST create a COSE_Key structure with the kid that was conveyed in the rs_cnf claim in the token response from the authorization server, and the key type symmetric. That structure is then included as the only element in the cnf structure, and the CBOR serialization of that cnf structure is used as the value for psk_identity, as shown in Figure 9. ๐Ÿงš

   { / cnf / 8 : {
      / COSE_Key / 1 : {
         / kty / 1 : / symmetric / 4,
         / kid / 2 : h'3d027833fc6267ce'
       }
     }
   }

Figure 9: Access Token Containing a Single kid Parameter

Here's what the CBOR serialization of the Figure 9 data structure looks like as a sequence of bytes in hexadecimal notation ๐Ÿ“:

A1 08 A1 01 A2 01 04 02 48 3D 02 78 33 FC 62 67 CE

As an alternative to uploading the access token, the client can put the most recent access token in the psk_identity field of the ClientKeyExchange message ๐ŸŒธ. To do that, the client MUST treat the contents of the access_token field from the AS-to-client response as opaque data, as specified in Section 4.2 of [RFC7925], and it must not perform any recoding. This lets the resource server pull the shared secret straight out of the cnf claim of the access token. ๐Ÿ”

DTLS 1.3 [RFC9147] doesn't use the ClientKeyExchange message at all ๐Ÿ™ˆ. For DTLS 1.3, the access token goes in the identity field of a PSKIdentity inside the PreSharedKeyExtension of the ClientHello.

If a resource server gets a ClientKeyExchange message containing a psk_identity with a length greater than zero, it MUST parse the contents of the psk_identity field as a CBOR data structure, and then process the contents as follows ๐Ÿง :

  • If the data contains a cnf field with a COSE_Key structure that has a kid, the resource server continues the DTLS handshake with the associated key that corresponds to that kid.
  • If the data comprises additional CWT information, that information must be stored as an access token for this DTLS association before the DTLS handshake continues.

If the contents of the psk_identity don't give enough information to select a valid access token for the requesting client, the resource server aborts the DTLS handshake with an illegal_parameter alert ๐Ÿ’€.

When the resource server receives an access token, it MUST check that the token is still valid, that the resource server is the intended destination (the audience of the token), and that the token was issued by an authorized authorization server ๐Ÿ‘‘. This specification implements access tokens as proof-of-possession tokens. So the access token is bound to a symmetric PoP key, and that key works as a shared secret between the client and the resource server. A resource server MUST have the capacity to store one access token for every proof-of-possession key of every authorized client ๐Ÿ“ฆ. The resource server may use token introspection [RFC7662] on the access token to get more info about that specific token. Using introspection is out of scope for this specification.

Here's the tea โ˜•: while the client can get the shared secret from the contents of the cnf parameter in the AS-to-client response, the resource server uses the information in the cnf claim of the access token to work out the actual secret when no explicit kid was provided in the psk_identity field. If key derivation is used, the cnf claim MUST contain a kid parameter, which the server uses as the IKM for key derivation, as described above ๐ŸŽ€.


3.4. Resource Access ๐Ÿฆ‹

Once a DTLS channel has been set up as described in either Sections 3.2 or 3.3, respectively, the client is authorized to access the resources covered by the access token it uploaded to the authz-info resource hosted by the resource server ๐ŸŒˆ.

When the DTLS channel is successfully established, the client and the resource server have proven that they can use their respective keying material. An access token that is bound to the client's keying material is associated with the channel ๐Ÿ”‘. According to Section 5.10.1 of [RFC9200], there should be only one access token for each client. New access tokens issued by the authorization server SHOULD replace previously issued access tokens for the respective client. That means the resource server needs a shared understanding with the authorization server about how access tokens are ordered ๐Ÿ“‹. The authorization server may, e.g., specify a cti claim for the access token (see Section 5.9.2 of [RFC9200]) to enforce a strict order โญ.

Any request the resource server receives on a DTLS channel that is tied to an access token through its keying material MUST be checked against the authorization rules that can be determined from the access token. The resource server MUST check every request to see whether the access token is still valid ๐Ÿ”. If the token has expired, the resource server MUST remove it. Incoming CoAP requests that aren't authorized with respect to any access token associated with the client MUST be rejected by the resource server with a 4.01 response ๐Ÿšซ. The response SHOULD include AS Request Creation Hints, as described in Section 5.2 of [RFC9200] ๐Ÿ’ก.

The resource server MUST NOT accept an incoming CoAP request as authorized if any of the following fails ๐Ÿ™…:

  1. The message was received on a secure channel that has been established using the procedure defined in this document.
  2. The authorization information tied to the sending client is valid.
  3. The request is destined for the resource server.
  4. The resource URI specified in the request is covered by the authorization information.
  5. The request method is an authorized action on the resource with respect to the authorization information.

Incoming CoAP requests received on a secure DTLS channel that are not authorized in this way MUST be rejected according to Section 5.10.2 of [RFC9200] ๐Ÿ˜ค:

  1. with response code 4.03 (Forbidden) when the resource URI specified in the request is not covered by the authorization information, and
  2. with response code 4.05 (Method Not Allowed) when the resource URI specified in the request is covered by the authorization information but not the requested action.

The client MUST make sure its keying material is still valid before it sends a request or processes a response ๐Ÿ”. If the client recently updated the access token (see Section 4), it must be ready for its request to still be handled according to the previous authorization rules, because there is no strict ordering between access token uploads and resource access messages ๐ŸŒ€. See also Section 7.2 for a discussion of access token processing.

If the client gets an error response containing AS Request Creation Hints (cf. Section 5.3 of [RFC9200]) to one of its requests, it SHOULD request a new access token from the authorization server so it can keep talking to the resource server ๐Ÿซถ.

Unauthorized requests received over a DTLS session SHOULD be treated as nonfatal by the resource server. In other words, the DTLS session SHOULD be kept alive until the associated access token has expired ๐Ÿงšโ€โ™€๏ธ๐Ÿ’œ.

4. Dynamic Update of Authorization Information โœจ

Okay so, resource servers must only use a new access token to update the authorization information for a DTLS session if the keying material bound to that token is the same as what was used in the DTLS handshake ๐Ÿ” That's the key part! Once access tokens are linked to an existing DTLS session's identifier, the permissions can get refreshed without touching the crypto keys between the client and the resource server. So the session keeps going, just with upgraded (or downgraded) permissions. It's giving efficiency, no cap ๐Ÿ’…

The client can update the authorization info on the resource server whenever it wants, without tearing down its DTLS session ๐Ÿฆ‹ It just asks the authorization server for a fresh access token for the action it wants on that resource, then uploads that token to the authz-info resource on the resource server. Iconic.

Figure 10 shows this flow, where the client asks for a new access token after a security association with the resource server has already been set up using this protocol ๐ŸŒธ If the client wants to update the authorization info, the token request MUST specify the key identifier of the proof-of-possession key used for the existing DTLS channel in the kid parameter of the client-to-AS request. The authorization server MUST verify that the specified kid is a valid verifier for a proof-of-possession token that was previously issued to the requesting client. If that's not the case, the client-to-AS request MUST be declined with the error code unsupported_pop_key, as defined in Section 5.8.3 of [RFC9200]. Not it. ๐Ÿ™…โ€โ™€๏ธ

When the authorization server hands out a new access token to update existing authorization info, it MUST include the specified kid parameter in that token ๐ŸŽ€ Then, a resource server MUST replace the authorization info of any existing DTLS session identified by that key identifier with the updated info. Bestie, this is the glue that connects the new token to the right session ๐Ÿซถ

      C                            RS                   AS
      | <===== DTLS channel =====> |                     |
      |        + Access Token      |                     |
      |                            |                     |
      | --- Token Request  ----------------------------> |
      |                            |                     |
      | <---------------------------- New Access Token - |
      |                           + Access Information   |
      |                            |                     |
      | --- Update /authz-info --> |                     |
      |     New Access Token       |                     |
      |                            |                     |
      | == Authorized Request ===> |                     |
      |                            |                     |
      | <=== Protected Resource == |                     |

              Figure 10: Overview of Dynamic Update Operation

5. Token Expiration โณ

The resource server MUST delete access tokens that are no longer valid ๐Ÿ—‘๏ธ DTLS associations set up under this profile are always tied to specific tokens (which can be swapped out with a dynamic update, as covered in Section 4). Tokens can expire or become invalid at any time, e.g., because they're just too old now ๐Ÿ’€ So the association might become useless at some point. That's why a resource server MUST terminate an existing DTLS association after the last access token linked to it has expired. Clean up your room, babe ๐Ÿงน

As specified in Section 5.10.3 of [RFC9200], the resource server MUST notify the client with an error response carrying the code 4.01 (Unauthorized) for any long-running request before it terminates the association ๐Ÿ˜ญ So the client gets a heads-up instead of just getting ghosted.


6. Secure Communication with an Authorization Server ๐Ÿ”’

As specified in the ACE framework (Sections 5.8 and 5.9 of [RFC9200]), the requesting entity (the resource server and/or the client) and the authorization server talk to each other through the token endpoint or the introspection endpoint ๐Ÿ’ฌ Using CoAP and DTLS for this communication is RECOMMENDED in this profile. Other protocols that meet the security requirements defined in Section 5 of [RFC9200] MAY be used instead ๐Ÿฆ‹

How credentials (e.g., PSK, RPK, X.509 cert) for using DTLS with the authorization server get set up is out of scope for this profile ๐Ÿ™ˆ Not our problem here, babe.

If other means of securing the communication with the authorization server are used, the communication security requirements from Section 6.2 of [RFC9200] still apply ๐Ÿ”


7. Security Considerations ๐Ÿšจ

This document specifies a profile for the Authentication and Authorization for Constrained Environments (ACE) framework [RFC9200]. Since it follows the framework's general approach, the general security considerations from Section 6 of [RFC9200] also apply to this profile. Read them, periodt ๐Ÿ“š

The authorization server must make sure that the keying material it gives the resource server for the client is actually tied to that client. Malicious clients might hand their access tokens, with their own permissions, over to other entities ๐Ÿ‘€ This problem can't be fully eliminated, sadly. But in RPK mode, clients should not be able to request access tokens for arbitrary public keys ๐Ÿ™…โ€โ™€๏ธ If a client can get the authorization server to issue a token for a public key without proving it has the matching private key, that opens the door to identity misbinding attacks, where the token ends up usable by someone other than the intended entity. Yikes ๐Ÿ˜ฑ So at some point the authorization server needs to check that the client can really use the private key that goes with its public key. No shortcuts!

When pre-shared keys provisioned by the authorization server are used, the security level depends on how random the PSKs are and how secure the TLS cipher suite and key exchange algorithm are ๐ŸŽฒ This spec targets constrained environments, so the message payloads exchanged between the client and the resource server are expected to be small and rare ๐ŸŒฑ CoAP [RFC7252] mandates implementing cipher suites with abbreviated, 8-byte tags for message integrity protection. For consistency, this profile requires implementing those same cipher suites. In application scenarios where full-width authentication tags are cheap compared to the total amount of data being sent, cipher suites with 16-byte integrity protection tags are preferred ๐Ÿ’–

The PSK mode of this profile offers a way to distribute authorization tokens together with a shared secret to a client and a server ๐Ÿงš Because this spec aims at constrained devices and uses CoAP [RFC7252] as the transfer protocol, at least the cipher suite TLS_PSK_WITH_AES_128_CCM_8 [RFC6655] should be supported. The access tokens and the matching shared secrets generated by the authorization server are expected to be short-lived enough to give similar forward-secrecy properties to ephemeral Diffie-Hellman (DHE) key exchange mechanisms โฑ๏ธ For longer-lived access tokens, DHE cipher suites should be used, i.e., cipher suites of the form TLS_DHE_PSK_* or TLS_ECDHE_PSK_* ๐Ÿ”ฅ

Constrained devices that use DTLS [RFC6347] [RFC9147] are inherently vulnerable to Denial of Service (DoS) attacks, because the handshake creates internal state on the device ๐Ÿ˜ฉ This is especially worrying when an adversary can intercept the initial cookie exchange and slip in forged messages with a valid cookie to continue the handshake. A similar issue exists with the unprotected authorization information endpoint when the resource server has to keep valid access tokens around for a long time. Adversaries could fill up the constrained resource server's internal storage for a very long time with intercepted or otherwise retrieved valid access tokens ๐Ÿ’€ To mitigate this, the resource server should set a time boundary after which an access token that hasn't been used by then gets deleted โฐ

The protection of access tokens stored at the authorization information endpoint depends on the keying material used between the authorization server and the resource server. The resource server must make sure it only processes access tokens that are integrity protected (and encrypted) by an authorization server that is authorized to provide access tokens for that resource server ๐Ÿ›ก๏ธ Main character security energy.

7.1. Reuse of Existing Sessions ๐Ÿ”„

To avoid the overhead of a repeated DTLS handshake, [RFC7925] recommends session resumption [RFC8446] to reuse session state from an earlier DTLS association, and thus requires client-side implementation ๐Ÿค“ In this specification, the DTLS session is subject to the authorization rules denoted by the access token that was used for the initial setup of the DTLS association. Enabling session resumption would require the server to transfer the authorization information with the session state in an encrypted SessionTicket to the client. Assuming the server uses long-lived keying material, this could open up attacks due to the lack of forward secrecy ๐Ÿ˜ฌ And here's the kicker: with this mechanism, a client can resume a DTLS session without proving it still has the PoP key. So session resumption should be used only in combination with reasonably short-lived PoP keys โณ

Since renegotiation of DTLS associations is prone to attacks too, [RFC7925] requires that clients decline any renegotiation attempt ๐Ÿ™…โ€โ™€๏ธ A server that wants to initiate rekeying therefore SHOULD periodically force a full handshake ๐Ÿ”

7.2. Multiple Access Tokens ๐ŸŽŸ๏ธ

Implementers SHOULD avoid using multiple access tokens for a client (see also Section 5.10.1 of [RFC9200]) ๐Ÿ’…

Even when a single access token per client is used, an attacker could compromise the dynamic update mechanism for existing DTLS connections by delaying or reordering packets destined for the authz-info endpoint ๐Ÿ‘ป So the order in which operations happen at the resource server (and therefore which authorization info is used to process a given client request) can't be guaranteed. Especially when later-issued access tokens reduce the client's permissions compared to the initial access token, it's impossible to guarantee that the reduction in authorization takes effect before the original token expires. Scary stuff, bestie ๐Ÿ˜ญโœจ

7.3. Out-of-Band Configuration

okay bestie, so before any of the protocol magic can happen, a bunch of info has to be swapped outside the flow this doc describes ๐Ÿ—๏ธโœจ the authorization server, the client, and the resource server all need certain stuff that has to come in through a side channel first. the auth server must have obtained authorization info about the client and the resource server that the resource owner approved, plus the matching keying material ๐Ÿ”‘ the resource server must have received authorization info the resource owner approved about its authorization managers, plus their keying material ๐Ÿงš the client must have obtained authorization info about the auth server that its owner approved, along with the keying material for that too ๐Ÿ’– and the client's owner must have approved the client talking to the resource server at all ๐Ÿ™…โ€โ™€๏ธ next, the client and the auth server must have a shared understanding of how the resource server gets identified, so the client grabs access tokens and keying material for the right resource server and not some random one ๐ŸŽฏ if the client gets a raw public key for the resource server, somebody has to check which resource server that key belongs to (its identifier and its authorization info) ๐Ÿ” and finally, all of this authorization info and keying material must be kept up to date ๐Ÿ”„ no stale keys allowed, periodt ๐Ÿ’…


8. Privacy Considerations ๐Ÿ™ˆ

this privacy stuff from Section 7 of [RFC9200] applies to this profile too, so go read that one as well ๐Ÿ“š

ok now the spicy part: an unprotected response to an unauthorized request can leak info about the resource server and/or its existing relationship with the client ๐Ÿ‘€ so it's advisable to put as little info as possible in an unencrypted response ๐Ÿคซ BUT once there's already a DTLS session between an authenticated client and the resource server, you MAY include more detailed info with an error response, so the client has enough to figure out that particular error ๐Ÿงฉ (the MAY is doing a lot of work there, ngl ๐Ÿ’€)

also, unprotected requests to the resource server can reveal stuff about the client, like which resources it's trying to reach or the data it wants to send over ๐Ÿ˜ญ so the client SHOULD NOT send confidential data in an unprotected request, no cap ๐Ÿšซ

and lowkey, even after the DTLS session is up, some info can still leak through observable message sizes and the source and destination addresses ๐Ÿซฃ the vibes are: encryption is great, but it isn't a magic invisibility cloak ๐Ÿงฅโœจ


9. IANA Considerations ๐ŸŽ€

this one's a registry moment ๐Ÿ“‹ the following registration has been made in the "ACE Profiles" registry, following the procedure specified in [RFC9200] ๐Ÿ’œ

Name:  coap_dtls
Description:  Profile for delegating client Authentication and
   Authorization for Constrained Environments by establishing a
   Datagram Transport Layer Security (DTLS) channel between resource-
   constrained nodes.
CBOR Value:  1
Reference:  RFC 9202

10. References ๐Ÿ“š

10.1. Normative References

these are the must-read ones, the foundation of the whole thing ๐Ÿ›๏ธ

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <https://www.rfc-editor.org/info/rfc2119>.

[RFC4279]  Eronen, P., Ed. and H. Tschofenig, Ed., "Pre-Shared Key
           Ciphersuites for Transport Layer Security (TLS)",
           RFC 4279, DOI 10.17487/RFC4279, December 2005,
           <https://www.rfc-editor.org/info/rfc4279>.

[RFC6347]  Rescorla, E. and N. Modadugu, "Datagram Transport Layer
           Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347,
           January 2012, <https://www.rfc-editor.org/info/rfc6347>.

[RFC6749]  Hardt, D., Ed., "The OAuth 2.0 Authorization Framework",
           RFC 6749, DOI 10.17487/RFC6749, October 2012,
           <https://www.rfc-editor.org/info/rfc6749>.

[RFC7250]  Wouters, P., Ed., Tschofenig, H., Ed., Gilmore, J.,
           Weiler, S., and T. Kivinen, "Using Raw Public Keys in
           Transport Layer Security (TLS) and Datagram Transport
           Layer Security (DTLS)", RFC 7250, DOI 10.17487/RFC7250,
           June 2014, <https://www.rfc-editor.org/info/rfc7250>.

[RFC7251]  McGrew, D., Bailey, D., Campagna, M., and R. Dugal, "AES-
           CCM Elliptic Curve Cryptography (ECC) Cipher Suites for
           TLS", RFC 7251, DOI 10.17487/RFC7251, June 2014,
           <https://www.rfc-editor.org/info/rfc7251>.

[RFC7252]  Shelby, Z., Hartke, K., and C. Bormann, "The Constrained
           Application Protocol (CoAP)", RFC 7252,
           DOI 10.17487/RFC7252, June 2014,
           <https://www.rfc-editor.org/info/rfc7252>.

[RFC7925]  Tschofenig, H., Ed. and T. Fossati, "Transport Layer
           Security (TLS) / Datagram Transport Layer Security (DTLS)
           Profiles for the Internet of Things", RFC 7925,
           DOI 10.17487/RFC7925, July 2016,
           <https://www.rfc-editor.org/info/rfc7925>.

[RFC8152]  Schaad, J., "CBOR Object Signing and Encryption (COSE)",
           RFC 8152, DOI 10.17487/RFC8152, July 2017,
           <https://www.rfc-editor.org/info/rfc8152>.

[RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
           2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
           May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8392]  Jones, M., Wahlstroem, E., Erdtman, S., and H. Tschofenig,
           "CBOR Web Token (CWT)", RFC 8392, DOI 10.17487/RFC8392,
           May 2018, <https://www.rfc-editor.org/info/rfc8392>.

[RFC8422]  Nir, Y., Josefsson, S., and M. Pegourie-Gonnard, "Elliptic
           Curve Cryptography (ECC) Cipher Suites for Transport Layer
           Security (TLS) Versions 1.2 and Earlier", RFC 8422,
           DOI 10.17487/RFC8422, August 2018,
           <https://www.rfc-editor.org/info/rfc8422>.

[RFC8747]  Jones, M., Seitz, L., Selander, G., Erdtman, S., and H.
           Tschofenig, "Proof-of-Possession Key Semantics for CBOR
           Web Tokens (CWTs)", RFC 8747, DOI 10.17487/RFC8747, March
           2020, <https://www.rfc-editor.org/info/rfc8747>.

[RFC8949]  Bormann, C. and P. Hoffman, "Concise Binary Object
           Representation (CBOR)", STD 94, RFC 8949,
           DOI 10.17487/RFC8949, December 2020,
           <https://www.rfc-editor.org/info/rfc8949>.

[RFC9147]  Rescorla, E., Tschofenig, H., and N. Modadugu, "The
           Datagram Transport Layer Security (DTLS) Protocol Version
           1.3", RFC 9147, DOI 10.17487/RFC9147, April 2022,
           <https://www.rfc-editor.org/info/rfc9147>.

[RFC9200]  Seitz, L., Selander, G., Wahlstroem, E., Erdtman, S., and
           H. Tschofenig, "Authentication and Authorization for
           Constrained Environments (ACE) Using the OAuth 2.0
           Framework (ACE-OAuth)", RFC 9200, DOI 10.17487/RFC9200,
           August 2022, <https://www.rfc-editor.org/info/rfc9200>.

[RFC9201]  Seitz, L., "Additional OAuth Parameters for Authentication
           and Authorization for Constrained Environments (ACE)",
           RFC 9201, DOI 10.17487/RFC9201, August 2022,
           <https://www.rfc-editor.org/info/rfc9201>.

10.2. Informative References

these ones are extra reading, nice to know but not required to get the spec ๐ŸŒธ

[RFC5869]  Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand
           Key Derivation Function (HKDF)", RFC 5869,
           DOI 10.17487/RFC5869, May 2010,
           <https://www.rfc-editor.org/info/rfc5869>.

[RFC6655]  McGrew, D. and D. Bailey, "AES-CCM Cipher Suites for
           Transport Layer Security (TLS)", RFC 6655,
           DOI 10.17487/RFC6655, July 2012,
           <https://www.rfc-editor.org/info/rfc6655>.

[RFC7662]  Richer, J., Ed., "OAuth 2.0 Token Introspection",
           RFC 7662, DOI 10.17487/RFC7662, October 2015,
           <https://www.rfc-editor.org/info/rfc7662>.

[RFC7748]  Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves
           for Security", RFC 7748, DOI 10.17487/RFC7748, January
           2016, <https://www.rfc-editor.org/info/rfc7748>.

[RFC8032]  Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital
           Signature Algorithm (EdDSA)", RFC 8032,
           DOI 10.17487/RFC8032, January 2017,
           <https://www.rfc-editor.org/info/rfc8032>.

[RFC8446]  Rescorla, E., "The Transport Layer Security (TLS) Protocol
           Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
           <https://www.rfc-editor.org/info/rfc8446>.

[RFC8610]  Birkholz, H., Vigano, C., and C. Bormann, "Concise Data
           Definition Language (CDDL): A Notational Convention to
           Express Concise Binary Object Representation (CBOR) and
           JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610,
           June 2019, <https://www.rfc-editor.org/info/rfc8610>.

Acknowledgments ๐Ÿซถ

huge thank yous to Jim Schaad for his contributions and reviews of this document, and to Ben Kaduk for his super thorough reviews ๐Ÿ™Œ thanks also to Paul Kyzivat for his review, and the authors would like to thank Marco Tiloca for his contributions ๐Ÿ’•

Ludwig Seitz worked on this document as part of the CelticNext projects CyberWI and CRITISEC, with funding from Vinnova ๐Ÿ‡ธ๐Ÿ‡ชโœจ


Authors' Addresses ๐Ÿ’Œ

Stefanie Gerdes
Universitรคt Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Phone: +49-421-218-63906
Email: gerdes@tzi.org

Olaf Bergmann
Universitรคt Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Phone: +49-421-218-63904
Email: bergmann@tzi.org

Carsten Bormann
Universitรคt Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Phone: +49-421-218-63921
Email: cabo@tzi.org

Gรถran Selander
Ericsson AB
Email: goran.selander@ericsson.com

Ludwig Seitz
Combitech
Djรคknegatan 31
SE-211 35 Malmรถ
Sweden
Email: ludwig.seitz@combitech.com
๐Ÿ“ฆ where this page comes from