RFC 8974
Extended Tokens and Stateless Clients in the Constrained Application Protocol (CoAP)
1. Introduction β¨
Okay so bestie, welcome to part 1 of RFC 8974, and honestly this one is giving main character energy π π¦ It's all about Extended Tokens and Stateless Clients in the Constrained Application Protocol (CoAP) π. I'm obsessed with it already, no cap.
Quick title-block tea first π: this doc is from the IETF, it's by K. Hartke (Ericsson) and M. Richardson (Sandelman), it's dated January 2021, and it's a Standards Track document π. It updates RFC 7252 and RFC 8323, which means it tweaks their definitions of the "TKL" field in the CoAP message header π. It doesn't obsolete anything, so the older stuff just gets a glow-up πΈ.
The abstract is basically the whole vibe β¨: it helps CoAP clients and intermediaries stop keeping per-request state, and to make that happen it adds a new, optional CoAP extension for longer token lengths π«Ά.
Status of This Memo π
This is an Internet Standards Track document π. It's a product of the IETF and reflects the consensus of the IETF community, and it got public review and was approved for publication by the IESG π₯. If you want more on Internet Standards, check Section 2 of RFC 7841 π§. For the current status, errata, and where to send feedback, go to https://www.rfc-editor.org/info/rfc8974 β.
Copyright Notice π
Copyright (c) 2021 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 stood when it was published, so read those carefully because they spell out your rights π. Any Code Components pulled out of this document must include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, per that same license π .
Table of Contents π¦
1. Introduction
1.1. Terminology
2. Extended Tokens
2.1. Extended Token Length (TKL) Field
2.2. Discovering Support
2.2.1. Extended-Token-Length Capability Option
2.2.2. Trial and Error
2.3. Intermediaries
3. Stateless Clients
3.1. Serializing Client State
3.2. Using Extended Tokens
3.3. Transmitting Messages
4. Stateless Intermediaries
4.1. Observing Resources
4.2. Block-Wise Transfers
4.3. Gateway Timeouts
4.4. Extended Tokens
5. Security Considerations
5.1. Extended Tokens
5.2. Stateless Clients and Intermediaries
6. IANA Considerations
6.1. CoAP Signaling Option Number
7. References
7.1. Normative References
7.2. Informative References
Appendix A. Updated Message Formats
A.1. CoAP over UDP
A.2. CoAP over TCP/TLS
A.3. CoAP over WebSockets
Acknowledgements
Authors' Addresses
1. Introduction π·
The Constrained Application Protocol (CoAP) [RFC7252] is a RESTful application-layer protocol made for constrained environments [RFC7228] π. In CoAP, clients (or intermediaries acting as clients) send requests to servers (or intermediaries acting as servers), and the servers answer those requests with responses β¨.
Here's the thing π: while a request is ongoing, the client usually has to hang onto some state so it can process the response when it finally shows up. CoAP tracks that state with a token, which is an opaque sequence of bytes. The client picks it, puts it in the request, and the server sends it back verbatim in any resulting response (Figure 1) π§.
+-----------------+ request with +------------+
| | | state identifier | |
| | | as token | |
| .-<-+->------|--------------------->|------. |
| _|_ | | | |
| / \ stored | | | |
| \___/ state | | | |
| | | | | |
| '->-+-<------|<---------------------|------' |
| | | response with | |
| v | token echoed back | |
+-----------------+ +------------+
Client Server
Figure 1: Token as an Identifier for Request State
Sometimes it's worth storing less state on the client, even if the messages get bigger π. A client can opt into this by serializing (parts of) its state into the token itself, then recovering that state from the token in the response (Figure 2) π.
+-----------------+ request with +------------+
| | | serialized state | |
| | | as token | |
| +--------|=====================>|------. |
| | | | |
| look ma, | | | |
| no state! | | | |
| | | | |
| +--------|<=====================|------' |
| | | response with | |
| v | token echoed back | |
+-----------------+ +------------+
Client Server
Figure 2: Token as Serialization of Request State
Section 3 of this document covers clients becoming "stateless" this way. (The word "stateless" is in quotes on purpose, because it's a bit of a simplification π. Such clients still have to keep per-server state and other kinds of state. So it's more accurate to say they're avoiding per-request state π .)
Section 4 extends those ideas to intermediaries, which may want to avoid keeping state not only for the requests they send to servers, but also for the requests they receive from clients π¦.
Serializing state into tokens has a limit, though π: both CoAP over UDP [RFC7252] and CoAP over reliable transports [RFC8323] cap the maximum token length at 8 bytes. To get around that, Section 2 of this document introduces a CoAP protocol extension for extended token lengths π₯.
The use case (avoiding per-request state) and the mechanism (extended token lengths) are closely related, but each one works on its own π. Some implementations may fit their state into just 8 bytes, and some may have other reasons to want extended token lengths π«Ά.
1.1. Terminology π
In this document, "stateless" refers to an implementation strategy for a client (or intermediary acting as a client) that doesn't have to keep state for each individual request it sends to a server (or intermediary acting as a server) β¨. The client still needs to keep state for each server it talks to, for things like token generation, message retransmission, and congestion control πΈ.
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 π.
2. Extended Tokens π§
This document updates the message formats defined for CoAP over UDP [RFC7252] and CoAP over TCP, TLS, and WebSockets [RFC8323] with a new definition of the "TKL" field π.
2.1. Extended Token Length (TKL) Field π¦
Here's the updated definition of the "TKL" field π:
Token Length (TKL): 4-bit unsigned integer. A value between 0 and 12, inclusive, indicates the length of the variable-length "Token" field in bytes. The other three values are reserved for special constructs:
- 13: An 8-bit unsigned integer directly precedes the "Token" field and indicates the length of the "Token" field minus 13.
- 14: A 16-bit unsigned integer in network byte order directly precedes the "Token" field and indicates the length of the "Token" field minus 269.
- 15: Reserved. This value MUST NOT be sent and MUST be processed as a message-format error.
All other fields keep their definitions πΈ.
The updated message formats are shown in Appendix A π«Ά.
The new "TKL" definition raises the maximum token length that can be represented in a message to 65804 bytes π. However, the maximum token length that sender and recipient implementations support may be shorter. For example, a constrained node of Class 1 [RFC7228] might only support extended token lengths up to 32 bytes π.
In CoAP over UDP, it's often worth keeping messages small enough to avoid IP fragmentation π. So the maximum practical token length may also be affected by the Path MTU (PMTU). See Section 4.6 of [RFC7252] for details π .
2.2. Discovering Support π·
Extended token lengths need support from server implementations π. A client implementation can discover that support in one of two ways:
- Where Capabilities and Settings Messages (CSMs) are available, such as in CoAP over TCP, support can be discovered using the Extended-Token-Length Capability Option defined in Section 2.2.1 β¨.
- Otherwise, such as in CoAP over UDP, support can only be discovered by trial and error, as described in Section 2.2.2 π§.
Part 1 of 5 done, bestie π Keep your eyes peeled for part 2, because the good stuff (stateless clients, the Capability Option, and more) is still coming π¦β¨.
2.2.1. Extended-Token-Length Capability Option β¨
okay so a server can use the totally optional Extended-Token-Length Capability Option π to tell everyone the biggest token it's willing to accept in a request. it's giving "here's my size limit, bestie" π
+=+=+===+=========+=======================+========+========+=======+
|#|C| R | Applies | Name | Format | Length | Base |
| | | | to | | | | Value |
+=+=+===+=========+=======================+========+========+=======+
|6| | | CSM | Extended-Token-Length | uint | 0-3 | 8 |
+-+-+---+---------+-----------------------+--------+--------+-------+
Table 1: The Extended-Token-Length Capability Option
C=Critical, R=Repeatable
ngl, per Section 3 of [RFC7252], the base value (which is also the value used when this option isn't implemented) is 8 πΈ
the active value of the Extended-Token-Length Option gets replaced every time the option is sent with a modified value π¦ and its starting value is its base value, so it begins at 8.
the option value MUST NOT be less than 8 or greater than 65804. if an option value less than 8 is received, the option MUST be ignored. if an option value greater than 65804 is received, the option value MUST be set to 65804. π«
any option value greater than 8 implies support for the new definition of the "TKL" field from Section 2.1. but a server showing support doesn't oblige a client to actually use token lengths greater than 8. no pressure, babe π«Ά
if a server gets a request with a token longer than what it indicated in its Extended-Token-Length Option, it MUST handle the request as a message-format error. π
if a server gets a request with a token whose length is less than, or equal to, what it indicated, but it's unwilling or unable to handle that token at the moment, it MUST NOT handle the request as a message-format error. instead, it SHOULD return a 5.03 (Service Unavailable) response. the vibe is "not right now, sweetie" and not "you messed up" π
the Extended-Token-Length Capability Option doesn't apply to responses. the sender of a request is just expected not to use a token longer than it's willing to accept in a response. π
2.2.2. Trial and Error β¨
a server implementation that doesn't support the updated definition of the "TKL" field from Section 2.1 will treat a request with a "TKL" field value outside the range 0 to 8 as a message-format error and reject it (Section 3 of [RFC7252]). so a client can figure out support by sending a request with an extended token length and seeing whether the server rejects it π΅οΈββοΈ
in CoAP over UDP, how a request gets rejected depends on the message type. a Confirmable message with a message-format error gets rejected with a Reset message (Section 4.2 of [RFC7252]). a Non-confirmable message with a message-format error either gets rejected with a Reset message or just gets silently ignored (Section 4.3 of [RFC7252]). so to reliably get a Reset message, it is therefore REQUIRED that clients use a Confirmable message for checking support. π―
as per RFC 7252, Reset messages are empty and don't contain a token. they only return the Message ID (Figure 3). they also don't say what caused the message-format error. so to avoid any confusion, it is therefore RECOMMENDED that clients use a request that has no potential message-format error other than the extended token length. β¨
+-----------------+ request message +------------+
| | | with extended | |
| | | token length | |
| .-<-+->------|--------------------->|------. |
| _|_ | | | |
| / \ stored | | | |
| \___/ state | | | |
| | | | | |
| '->-+-<------|<---------------------|------' |
| | | Reset message | |
| v | with only message | |
+-----------------+ ID echoed back +------------+
Client Server
Figure 3: A Confirmable Request with an Extended Token Is Rejected with a Reset Message If the Server Does Not Have Support
an example of a suitable request is a GET request in a Confirmable message that includes only an If-None-Match option and a token of the greatest length the client intends to use. if any response comes back with that same token echoed, it means the server supports tokens up to that length π§
since network addresses can change, a client SHOULD NOT assume that a server supports extended token lengths for an unlimited amount of time. unless it has extra info, the client should assume that addresses (and therefore extended token lengths) are valid for a minimum of 1800 s and a maximum of 86400 s (1 day). β°
a client may also use extra inputs to figure this out. for example, a client may assume that a server on the same subnet has a similar address lifetime to its own. the client may use DHCP lease times or Router Advertisements to set the limits. for servers that aren't local, if the server was looked up using DNS, then the DNS resource record has a Time To Live (TTL), and the extended token length should only be kept for that long. πΈ
if a server supports extended token lengths but gets a request with a token it's unwilling or unable to handle, it MUST NOT reject the message, because that would imply that extended token lengths aren't supported at all. instead, if the server can't handle the request right now, it SHOULD return a 5.03 (Service Unavailable) response. if the server will never be able to handle the request (e.g., because the token is too large), it SHOULD return a 4.00 (Bad Request) response. π
β¨ Design Note: the requirement to return an error response when a token can't be handled might sound a bit contradictory, since returning the error response means the server also has to return the token it can't handle. but processing a request usually involves several steps, from receiving the message to passing it to application logic. the idea is that a server implementing this extension supports large tokens at least in its first few processing steps, enough to send back an error response instead of a Reset message. π
β¨ Design Note: to keep trial-and-error discovery from getting too complicated, no effort is made to indicate the maximum supported token length. a client implementation would probably already pick the shortest token possible for the task (like being stateless, as described in Section 3), so it probably couldn't shorten the token any further anyway if a server indicated a lower limit. π§
2.3. Intermediaries π¦
tokens are a hop-by-hop feature. if there are one or more intermediaries between a client and a server, every token is scoped to the exchange between the client-role node and the server-role node it's immediately talking to. π
when an intermediary receives a request, the only requirement is that it echoes the token back in any resulting response. there's no requirement or expectation that an intermediary passes a client's token on to a server, or that an intermediary uses extended token lengths itself in its own request to satisfy a request with an extended token length. discovery needs to happen for each hop where extended token lengths are going to be used. π
3. Stateless Clients π§ββοΈ
a client can be let off the hook from keeping per-request state, like this:
- the client serializes (parts of) its per-request state into a sequence of bytes and sends those bytes as the token of its request to the server. π¦
- the server returns the token verbatim in the response to the client, which lets the client recover the state and process the response as if it had kept the state locally. π
since servers are just expected to return any token verbatim to the client, this implementation strategy for clients doesn't affect the interoperability of client and server implementations. however, there are a number of significant, nonobvious implications (e.g., related to security and other CoAP protocol features) that client implementations need to take into consideration. π
the following subsections talk through some of these considerations. π«Ά
3.1. Serializing Client State π
the format of the serialized state is generally an implementation detail of the client and is opaque to the server. but serialized state information is an extremely attractive target for both unwanted nodes (e.g., on-path attackers) and wanted nodes (e.g., any configured forward proxy) on the path. so the serialization format needs to include security measures like these:
- A client SHOULD protect the integrity of the state information serialized in a token. π‘οΈ
- Even when the integrity of the serialized state is protected, an attacker may still replay a response, making the client believe it sent the same request twice. for this reason, the client SHOULD implement replay protection (e.g., by using sequence numbers and a replay window). for replay protection, integrity protection is REQUIRED. π±
- if processing a response without keeping request state is sensitive to the time elapsed since sending the request, then the client SHOULD include freshness information (e.g., a timestamp) in the serialized state and reject any response where that freshness information isn't fresh enough. β³
- information in the serialized state may be privacy sensitive. a client SHOULD encrypt the serialized state if it contains privacy-sensitive information that an attacker wouldn't otherwise get. π
- when a client changes the format of the serialized state, it SHOULD prevent false interoperability with the previous format (e.g., by changing the key used for integrity protection or changing a field in the serialized state). π
3.2. Using Extended Tokens β¨
okay bestie, so if a client is counting on the server to handle extended token lengths (Section 2) so it can stay stateless π¦, it has to do a discovery of support (Section 2.2) first. Only after that can it be stateless π .
This discovery MUST happen the stateful way, meaning the client keeps state for the request (Figure 4). ngl this part is so important π If the client was stateless from the very start and the server doesn't support extended tokens, then there's no way to process an error message π. The state isn't stored on the client, and it also doesn't come back in the Reset message (Figure 5).
+-----------------+ dummy request +------------+
| | | with extended | |
| | | token | |
| .-<-+->------|=====================>|------. |
| _|_ | | | |
| / \ stored | | | |
| \___/ state | | | |
| | | | | |
| '->-+-<------|<=====================|------' |
| | | response with | |
| | | extended token | |
| | | echoed back | |
| | | | |
| | | | |
| | | request with | |
| | | serialized state | |
| | | as token | |
| +--------|=====================>|------. |
| | | | |
| look ma, | | | |
| no state! | | | |
| | | | |
| +--------|<=====================|------' |
| | | response with | |
| v | token echoed back | |
+-----------------+ +------------+
Client Server
Figure 4: Depending on Extended Tokens for Being Stateless First Requires a Successful Stateful Discovery of Support
+-----------------+ dummy request +------------+
| | | with extended | |
| | | token | |
| +--------|=====================>|------. |
| | | | |
| | | | |
| | | | |
| | | | |
| ???|<---------------------|------' |
| | Reset message | |
| | with only message | |
+-----------------+ ID echoed back +------------+
Client Server
Figure 5: Stateless Discovery of Support Does Not Work
In environments where support can be reliably figured out some other way, doing the discovery of support is OPTIONAL πΈ An example of this is the Constrained Join Protocol (CoJP) in a 6TiSCH network [6TISCH-MIN-SEC], where support for extended tokens is required from all relevant parties π§
3.3. Transmitting Messages π
In CoAP over UDP [RFC7252], a client gets to choose between Confirmable and Non-confirmable messages for requests. When it uses Non-confirmable messages, the client doesn't have to keep any message-exchange state, which helps with the whole avoiding-state goal π«Ά When it uses Confirmable messages, though, the client needs to keep message-exchange state so it can do retransmissions and handle Acknowledgement and Reset messages. So Non-confirmable messages are the better fit for avoiding state β¨ Either way, the client still needs to keep congestion-control state, meaning it maintains state for each node it talks to and enforces limits like NSTART π
As per Section 5.2 of [RFC7252], a client has to be ready to receive a response as a piggybacked response, a separate response, or a Non-confirmable response, no matter which message type it used for the request. A stateless client MUST handle these response types like this π
- If a piggybacked response passes the checks for token integrity and freshness (Section 3.1), the client processes the message as specified in RFC 7252. Otherwise, it processes the acknowledgement portion of the message as specified in RFC 7252 and silently discards the response portion π¦
- If a separate response passes the checks for token integrity and freshness, the client processes the message as specified in RFC 7252. Otherwise, it rejects the message as specified in Section 4.2 of [RFC7252] π
- If a Non-confirmable response passes the checks for token integrity and freshness, the client processes the message as specified in RFC 7252. Otherwise, it rejects the message as specified in Section 4.3 of [RFC7252] π
4. Stateless Intermediaries β¨
Tokens are a hop-by-hop feature π§ If a client makes a request to an intermediary, that intermediary needs to store the client's token (along with the client's transport address) while it makes its own request towards the origin server and waits for the response. When the intermediary gets the response, it looks up the client's token and transport address for the received request and sends an appropriate response back to the client π
An intermediary might want to be "stateless" not only as a client but also as a server, which means it's freed from storing the client information for the requests it receives π
This can work by serializing the client information along with the request state into the token sent towards the origin server. When the intermediary receives the response, it can recover the client information from the token and use it to satisfy the client's request. So the intermediary doesn't need to store the information itself π«Ά
The following subsections talk through some considerations for this approach π
4.1. Observing Resources π
One drawback of this approach is that an intermediary without request state can't aggregate multiple requests for the same target resource, and that can really hurt efficiency π Specifically, when clients observe [RFC7641] the same resource, aggregating requests is REQUIRED (Section 3.1 of [RFC7641]). This requirement can't be satisfied without keeping request state π
It also gets messy: an intermediary that doesn't track the clients observing a resource can't tell whether those clients are still interested in getting further notifications (Section 3.5 of [RFC7641]), or whether they want to cancel an observation (Section 3.6 of [RFC7641]) π
So an intermediary MUST NOT include an Observe Option in requests it sends unless it keeps both the request state for the requests it sends and the client information for the requests it receives π₯
4.2. Block-Wise Transfers π§©
When block-wise transfers are used [RFC7959], a server might not be able to tell apart blocks that came from different clients once an intermediary has forwarded them. The intermediary needs to make sure this doesn't lead to inconsistent resource state, so it keeps distinct block-wise request operations on the same resource apart, e.g., by using the Request-Tag Option [ECHO-REQUEST-TAG] πΈ
4.3. Gateway Timeouts β°
As per Section 5.7.1 of [RFC7252], an intermediary is REQUIRED to return a 5.04 (Gateway Timeout) response if it can't get a response within a timeout. But if an intermediary doesn't keep the client information for the requests it receives, it can't return such a response. So in this case, the gateway can't return that response, and it can't implement such a timeout either π©
4.4. Extended Tokens π·
A client may use extended token lengths in a request to an intermediary that wants to be "stateless". This means such an intermediary may have to serialize potentially very large client information into its token towards the origin server. The tokens can grow even more as they go along a chain of intermediaries that all want to be "stateless" π
Intermediaries SHOULD limit the size of the client information they serialize into their own tokens. An intermediary can do this, for example, by limiting the extended token lengths it accepts from its clients (see Section 2.2), or by keeping the client information locally when that information goes over the limit (i.e., not being "stateless") π
5. Security Considerations π¨
5.1. Extended Tokens π‘οΈ
Tokens that are significantly larger than the 8 bytes specified in RFC 7252 have implications, especially for nodes with constrained memory size, and those implications need to be mitigated π± A node in the server role that supports extended token lengths may be vulnerable to a denial of service when an attacker (either on-path or a malicious client) sends large tokens to fill up the memory of the node. Implementations need to be prepared to handle such messages π
5.2. Stateless Clients and Intermediaries β¨
okay so putting the state a client needs to process a response inside the token is giving "clever," but it comes with some seriously sneaky security and privacy problems π you have to mitigate them, see Section 3.1 for the recs π«Ά
on top of the format stuff over there, implementations need to make sure they're not vulnerable to maliciously crafted, delayed, or replayed tokens π
it's generally expected that encryption, integrity protection, and replay protection for the serialized state are appropriate π
and here's why integrity matters so much: without integrity and replay protection, an on-path attacker or a rogue server/intermediary could send back a state (either a modified one in a reply, or an unsolicited one) and mess with the client's internal state. not cute π
that's exactly why integrity protection on the token is always recommended. no exceptions bestie π
could there be some super specific case where, after a really careful and detailed look at possible attacks, someone decides the crypto protections don't add any value? maybe! the authors haven't found one yet, but it's a local decision π§
also, the encrypted state is created by the sending node and decrypted by that same node when a response comes back. the key is never shared with any other system, so picking the encryption scheme and generating the key is purely a local matter πβ¨
when encryption is used, AES-CCM [RFC3610] with a 64-bit tag is recommended, combined with a sequence number and a replay window. this choice is informed by the hardware acceleration that's available on many constrained systems π₯ if a different algorithm is accelerated on the sender and it's similar or stronger in strength, then it SHOULD be preferred π and if privacy of the state isn't required and encryption isn't needed, HMAC-SHA-256 [RFC6234] combined with a sequence number and a replay window may be used π¦
now the replay window size. it depends on how many requests need to be outstanding at once, which you can figure out from how fast new ones get made and how long responses are expected to take π
for example, say the CoAP MAX_TRANSMIT_WAIT is 93 s (Section 4.8.2 of [RFC7252]). any request not answered within 93 s is considered failed. at a request rate of one request per 10 s, at most 10 (ceil(9.3)) requests can be outstanding at a time, and any convenient replay window larger than 20 will work π since replay windows are often implemented with a sliding window and a bit, a 32-bit window would be sufficient β¨
for use cases where requests are relayed from another node, you can estimate the request rate from the total link capacity allocated for that kind of traffic. an alternate view looks at how many IPv6 Neighbor Cache Entries (NCEs) the system can afford to allocate for this use πΈ
when you use an encryption mode that depends on a nonce, like AES-CCM, reusing the same nonce under the same key makes the cipher fail catastrophically. the worst π±
if a nonce is ever used for more than one encryption operation with the same key, the same key stream gets used to encrypt both plaintexts, and the confidentiality guarantees are voided π devices with low-quality entropy sources are a real concern here. that's typical of constrained devices, which, iykyk, are also a natural candidate for the stateless mechanism in this document π₯Ί so they need to carefully pick a nonce-generation mechanism that provides the uniqueness guarantee above π«Ά
and for keeping nonces unique without causing excessive wear of flash memory, [RFC8613], Appendix B.1.1 ("Sender Sequence Number") gives you a model π
6. IANA Considerations π
6.1. CoAP Signaling Option Number
the following entry has been added to the "CoAP Signaling Option Numbers" registry within the "CoRE Parameters" registry. main character energy π
+============+========+=======================+===========+
| Applies to | Number | Name | Reference |
+============+========+=======================+===========+
| 7.01 | 6 | Extended-Token-Length | RFC 8974 |
+------------+--------+-----------------------+-----------+
Table 2: CoAP Signaling Option Number
7. References π
7.1. Normative References
- [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>. - [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>. - [RFC7641] Hartke, K., "Observing Resources in the Constrained Application Protocol (CoAP)", RFC 7641, DOI 10.17487/RFC7641, September 2015,
<https://www.rfc-editor.org/info/rfc7641>. - [RFC7959] Bormann, C. and Z. Shelby, Ed., "Block-Wise Transfers in the Constrained Application Protocol (CoAP)", RFC 7959, DOI 10.17487/RFC7959, August 2016,
<https://www.rfc-editor.org/info/rfc7959>. - [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>. - [RFC8323] Bormann, C., Lemay, S., Tschofenig, H., Hartke, K., Silverajan, B., and B. Raymor, Ed., "CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets", RFC 8323, DOI 10.17487/RFC8323, February 2018,
<https://www.rfc-editor.org/info/rfc8323>.
7.2. Informative References
- [6TISCH-MIN-SEC] Vucinic, M., Simon, J., Pister, K., and M. Richardson, "Constrained Join Protocol (CoJP) for 6TiSCH", Work in Progress, Internet-Draft, draft-ietf-6tisch-minimal-security-15, 10 December 2019,
<https://tools.ietf.org/html/draft-ietf-6tisch-minimal-security-15>. - [ECHO-REQUEST-TAG] AmsΓΌss, C., Mattsson, J. P., and G. Selander, "CoAP: Echo, Request-Tag, and Token Processing", Work in Progress, Internet-Draft, draft-ietf-core-echo-request-tag-11, 2 November 2020,
<https://tools.ietf.org/html/draft-ietf-core-echo-request-tag-11>. - [RFC3610] Whiting, D., Housley, R., and N. Ferguson, "Counter with CBC-MAC (CCM)", RFC 3610, DOI 10.17487/RFC3610, September 2003,
<https://www.rfc-editor.org/info/rfc3610>. - [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, May 2011,
<https://www.rfc-editor.org/info/rfc6234>. - [RFC7228] Bormann, C., Ersue, M., and A. Keranen, "Terminology for Constrained-Node Networks", RFC 7228, DOI 10.17487/RFC7228, May 2014,
<https://www.rfc-editor.org/info/rfc7228>. - [RFC8613] Selander, G., Mattsson, J., Palombini, F., and L. Seitz, "Object Security for Constrained RESTful Environments (OSCORE)", RFC 8613, DOI 10.17487/RFC8613, July 2019,
<https://www.rfc-editor.org/info/rfc8613>.
Appendix A. Updated Message Formats π§
in Section 2, this document updates the CoAP message formats by specifying a new definition of the "TKL" field in the message header π as an alternative way of presenting this update, this appendix shows the CoAP message formats for CoAP over UDP [RFC7252] and CoAP over TCP, TLS, and WebSockets [RFC8323] with the new definition applied π¦
A.1. CoAP over UDP
0 1 2 3 4 5 6 7
+-------+-------+---------------+
| | | |
| Ver | T | TKL | 1 byte
| | | |
+-------+-------+---------------+
| |
| Code | 1 byte
| |
+-------------------------------+
| |
| |
| |
+- Message ID -+ 2 bytes
| |
| |
| |
+-------------------------------+
\ \
/ TKL / 0-2 bytes
\ (extended) \
+-------------------------------+
\ \
/ Token / 0-65804 bytes
\ \
+-------------------------------+
\ \
/ /
\ \
/ Options / 0 or more bytes
\ \
/ /
\ \
+---------------+---------------+
| | |
| 15 | 15 | 1 byte (if payload)
| | |
+---------------+---------------+
\ \
/ /
\ \
/ Payload / 0 or more bytes
\ \
/ /
\ \
+-------------------------------+
Wait, I should be upfront: this is part 5 and I'm continuing directly from A.1, so here goes! π
A.2. CoAP over TCP/TLS π¦
Okay so this is the CoAP-over-TCP/TLS layout, and bestie, it's giving familiar but with a little twist. The header bits are the same spirit as before, just with the extended fields tucked in where they're needed. π
0 1 2 3 4 5 6 7
+---------------+---------------+
| | |
| Len | TKL | 1 byte
| | |
+---------------+---------------+
\ \
/ Len / 0-4 bytes
\ (extended) \
+-------------------------------+
| |
| Code | 1 byte
| |
+-------------------------------+
\ \
/ TKL / 0-2 bytes
\ (extended) \
+-------------------------------+
\ \
/ Token / 0-65804 bytes
\ \
+-------------------------------+
\ \
/ /
\ \
/ Options / 0 or more bytes
\ \
/ /
\ \
+---------------+---------------+
| | |
| 15 | 15 | 1 byte (if payload)
| | |
+---------------+---------------+
\ \
/ /
\ \
/ Payload / 0 or more bytes
\ \
/ /
\ \
+-------------------------------+
A.3. CoAP over WebSockets πΈ
Now the WebSockets version is lowkey the same energy, but the first field is a fixed 0 instead of Len, so the framing is doing its own thing. Slay the consistency. β¨
0 1 2 3 4 5 6 7
+---------------+---------------+
| | |
| 0 | TKL | 1 byte
| | |
+---------------+---------------+
| |
| Code | 1 byte
| |
+-------------------------------+
\ \
/ TKL / 0-2 bytes
\ (extended) \
+-------------------------------+
\ \
/ Token / 0-65804 bytes
\ \
+-------------------------------+
\ \
/ /
\ \
/ Options / 0 or more bytes
\ \
/ /
\ \
+---------------+---------------+
| | |
| 15 | 15 | 1 byte (if payload)
| | |
+---------------+---------------+
\ \
/ /
\ \
/ Payload / 0 or more bytes
\ \
/ /
\ \
+-------------------------------+
Acknowledgements π«Ά
This document is based on the requirements of, and work on, "Constrained Join Protocol (CoJP) for 6TiSCH" (January 2020) by MaliΕ‘a VuΔiniΔ, Jonathan Simon, Kris Pister, and Michael Richardson.
Thanks to Christian AmsΓΌss, Carsten Bormann, Roman Danyliw, Christer Holmberg, Benjamin Kaduk, Ari KerΓ€nen, Erik Kline, Murray Kucherawy, Warren Kumari, Barry Leiba, David Mandelberg, Dan Romascanu, Jim Schaad, GΓΆran Selander, MaliΕ‘a VuΔiniΔ, Γric Vyncke, and Robert Wilton for helpful comments and discussions that have shaped the document.
Special thanks to John Mattsson for his contributions to the security considerations of the document, and to Thomas Fossati for his in-depth review, copious comments, and suggested text. π
Authors' Addresses π
Klaus Hartke Ericsson Torshamnsgatan 23 SE-16483 Stockholm Sweden
Email: klaus.hartke@ericsson.com
Michael C. Richardson Sandelman Software Works
Email: mcr+ietf@sandelman.ca URI: http://www.sandelman.ca/
That's a wrap on RFC 8974! π Thank you for being the best study buddy, bestie. ππ§
π¦ where this page comes from
- ietf: rfc8974 2021-01
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms