RFC 8609

Content-Centric Networking (CCNx) Messages in TLV Format

πŸ“… published July 2019, from ietf

Content-Centric Networking (CCNx) Messages in TLV Format ✨

Okay bestie, this one is a whole RFC glow-up πŸŽ€ It's from the IRTF (not the IETF, so it's experimental and not a standard), and it's the spec for how CCNx messages get packed into TLV packets πŸ“¦. Let's get into it πŸ’…

The title block, the tea β˜•:

  • Number: RFC 8609 πŸ¦‹
  • Authors: M. Mosko (PARC, Inc.), I. Solis (LinkedIn), and C. Wood (University of California Irvine) 🌸
  • Category: Experimental πŸ§ͺ
  • Stream/Group: Internet Research Task Force (IRTF), from the Information Centric Networking research group (ICNRG) 🌈
  • ISSN: 2070-1721 πŸ’œ
  • Date: July 2019 πŸ“…

Nothing in the title block says this document obsoletes or updates another RFC, so it's a clean slate ✨


Abstract

CCNx is a network protocol that uses a hierarchical name to forward requests and to match responses to requests 🌸 This doc is the encoding part of the story: it tells you how CCNx messages look in a TLV packet format, which TLV types each message element uses, and how each value is encoded 🧚 The meaning of those messages lives in the encoding-independent CCNx Semantics spec, so these two docs are a whole team 🫢

It was reviewed widely by ICNRG folks, and there are two full implementations in active use, which is honestly iconic for an experimental spec πŸ”₯

Status of This Memo

Okay, the fine print, but make it cute πŸŽ€ This is not an Internet Standards Track spec. It's published so people can look at it, try implementing it, and evaluate it πŸ”

It defines an Experimental Protocol for the Internet community, and it's an IRTF product. The IRTF shares research and development results, and those results might not be ready for deployment, so don't ship it to prod πŸ’€ It represents the consensus of the Information-Centric Networking Research Group. Anything the IRSG approves is not a candidate for any Internet Standard level, see Section 2 of RFC 7841 πŸ’…

Errata, status updates, and feedback all live at https://www.rfc-editor.org/info/rfc8609 πŸ¦‹

Copyright (c) 2019 IETF Trust and the persons identified as the document authors. All rights reserved πŸ’–

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they were on the publication date. Read those carefully, because they spell out your rights and restrictions for this doc πŸ“œ

Table of Contents

Here's the whole roadmap, all 10 parts of it, so you know where we're headed πŸ—ΊοΈ I'm keeping the numbering exactly as the original has it, because the text points back to these sections all the time 🫢

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . .   3
  1.1.  Requirements Language . . . . . . . . . . . . . . . . . .   5
2.  Definitions . . . . . . . . . . . . . . . . . . . . . . . . .   5
3.  Type-Length-Value (TLV) Packets . . . . . . . . . . . . . . .   5
  3.1.  Overall Packet Format . . . . . . . . . . . . . . . . . .   7
  3.2.  Fixed Headers . . . . . . . . . . . . . . . . . . . . . .   8
    3.2.1.  Interest Fixed Header . . . . . . . . . . . . . . . .   9
      3.2.1.1.  Interest HopLimit . . . . . . . . . . . . . . . .   9
    3.2.2.  Content Object Fixed Header . . . . . . . . . . . . .   9
    3.2.3.  Interest Return Fixed Header  . . . . . . . . . . . .  10
      3.2.3.1.  Interest Return HopLimit  . . . . . . . . . . . .  10
      3.2.3.2.  Interest Return Flags . . . . . . . . . . . . . .  10
      3.2.3.3.  Return Code . . . . . . . . . . . . . . . . . . .  10
  3.3.  Global Formats  . . . . . . . . . . . . . . . . . . . . .  11
    3.3.1.  Pad . . . . . . . . . . . . . . . . . . . . . . . . .  11
    3.3.2.  Organization-Specific TLVs  . . . . . . . . . . . . .  12
    3.3.3.  Hash Format . . . . . . . . . . . . . . . . . . . . .  12
    3.3.4.  Link  . . . . . . . . . . . . . . . . . . . . . . . .  13
  3.4.  Hop-by-Hop TLV Headers  . . . . . . . . . . . . . . . . .  14
    3.4.1.  Interest Lifetime . . . . . . . . . . . . . . . . . .  14
    3.4.2.  Recommended Cache Time  . . . . . . . . . . . . . . .  15
    3.4.3.  Message Hash  . . . . . . . . . . . . . . . . . . . .  16
  3.5.  Top-Level Types . . . . . . . . . . . . . . . . . . . . .  17
  3.6.  CCNx Message TLV  . . . . . . . . . . . . . . . . . . . .  18
    3.6.1.  Name  . . . . . . . . . . . . . . . . . . . . . . . .  19
      3.6.1.1.  Name Segments . . . . . . . . . . . . . . . . . .  20
      3.6.1.2.  Interest Payload ID . . . . . . . . . . . . . . .  20
    3.6.2.  Message TLVs  . . . . . . . . . . . . . . . . . . . .  21
      3.6.2.1.  Interest Message TLVs . . . . . . . . . . . . . .  21
      3.6.2.2.  Content Object Message TLVs . . . . . . . . . . .  23
    3.6.3.  Payload . . . . . . . . . . . . . . . . . . . . . . .  25
    3.6.4.  Validation  . . . . . . . . . . . . . . . . . . . . .  25
      3.6.4.1.  Validation Algorithm  . . . . . . . . . . . . . .  25
      3.6.4.2.  Validation Payload  . . . . . . . . . . . . . . .  32
4.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  33
  4.1.  Packet Type Registry  . . . . . . . . . . . . . . . . . .  33
  4.2.  Interest Return Code Registry . . . . . . . . . . . . . .  34
  4.3.  Hop-by-Hop Type Registry  . . . . . . . . . . . . . . . .  35
  4.4.  Top-Level Type Registry . . . . . . . . . . . . . . . . .  36
  4.5.  Name Segment Type Registry  . . . . . . . . . . . . . . .  37
  4.6.  Message Type Registry . . . . . . . . . . . . . . . . . .  37
  4.7.  Payload Type Registry . . . . . . . . . . . . . . . . . .  38
  4.8.  Validation Algorithm Type Registry  . . . . . . . . . . .  39
  4.9.  Validation-Dependent Data Type Registry . . . . . . . . .  40
  4.10. Hash Function Type Registry . . . . . . . . . . . . . . .  40
5.  Security Considerations . . . . . . . . . . . . . . . . . . .  41
6.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  44
  6.1.  Normative References  . . . . . . . . . . . . . . . . . .  44
  6.2.  Informative References  . . . . . . . . . . . . . . . . .  44
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  46

1. Introduction 🌸

Okay, so the big picture ✨ This document is a Type-Length-Value (TLV) packet format plus the TLV type and value encodings for CCNx messages πŸ“¦ If you want the full, encoding-free rundown of CCNx messages and message elements, that lives in [RFC8569] πŸ“–

Here's the core CCNx vibe 🫢 It uses a hierarchical name to forward requests and match responses to requests. There are no endpoint addresses, because the Internet Protocol handles those. A request can narrow down the response by the public key of its signer or by its cryptographic hash πŸ” Every CCNx forwarder along the path does the name matching and the restriction checking, so the work is spread out 🧚 CCNx also fits into the bigger Information-Centric Networking (ICN) family of protocols [RFC7927] 🌈

This doc uses a TLV scheme with a fixed 2-byte T and a fixed 2-byte L field πŸŽ€ The reason for going fixed-size is in Section 5. The short version is that it avoids aliases (the same value encoded more than one way) and makes validation way easier πŸ’… Here's the twist: unlike a lot of TLV stuff in networking, every network hop has to evaluate the encoding. So even tiny validation delays at each hop can add up to a big forwarding delay 😭 If your packets are tiny or your links are slow and those extra bytes start to matter, you can use a TLV compression protocol, for example [compress] and [CCNxz] πŸ¦‹

Terminology check πŸ“ This doc uses CCNx Packet, CCNx Message, and CCNx Message TLV. A CCNx Packet is the entire Layer 3 datagram, see Section 3.1. A CCNx Message is the ABNF token defined in the CCNx Semantics document [RFC8569]. A CCNx Message TLV is the encoding of a CCNx Message, see Section 3.6 🧠

This document specifies:

  • the CCNx Packet format,
  • the CCNx Message TLV format,
  • the TLV types used by CCNx messages,
  • the encoding of values for each type,
  • top-level types that exist at the outermost containment,
  • Interest TLVs that exist within Interest containment, and
  • Content Object TLVs that exist within Content Object containment πŸ’–

It's supplemented by these two docs:

  • [RFC8569], which covers message semantics and the protocol operation for Interest and Content Object, including the Interest Return protocol 🌟
  • [CCNxURI], which covers the CCNx URI notation πŸ”—

Type values in Section 4 match the IANA-assigned numbers for CCNx, and that section uses the symbolic names defined there 🏷️ Also, all TLV type values are relative to their parent containers. So each level of a nested TLV can have a "type = 1" that means something completely different 🀯 Lowkey chaotic, but that's the design πŸ’…

Packets get drawn as 32-bit wide words in ASCII art 🎨 Because TLVs nest, have optional fields, and come in variable sizes, there's no tidy way to draw every possibility 😭 So the convention is: fields in vertical bars | are exact bit widths, and fields marked with a forward slash / are variable width. Those usually get padded out to word alignment so the pictures stay readable πŸ¦‹

This doc represents the consensus of the ICN RG πŸ’œ It's the first ICN protocol from the RG, built from the early CCNx protocol [nnc] with major revisions and input from the ICN community and RG members 🌈 Several ICN folks and RG members gave it a close read. The authors and RG chairs approve of the contents ✨ It's sponsored by the IRTF and is not issued by the IETF, and it's not an IETF standard. It's experimental, so it might not fit every application, and the spec could change later 🧚

1.1. Requirements Language

Here's the BCP 14 part, so pay attention πŸŽ€ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" are interpreted as described in BCP 14 [RFC2119] [RFC8174], but only when they show up in ALL CAPS like that πŸ’… Lowercase versions are just regular words 🫢


Part 1 of 10. Keep going, there's more CCNx tea coming πŸ“

3. Type-Length-Value (TLV) Packets ✨

okay bestie, TLV time πŸŽ€ We use 16-bit Type and 16-bit Length fields to encode TLV-based packets. That gives you 65,536 possible types and value fields up to 64 KiB long πŸ’– With 65,536 possible types at each level of TLV encoding, there's plenty of room for basic protocol types, plus lots of space for experimentation, application use, vendor extensions, and growth πŸ¦‹ This encoding does not allow jumbo packets beyond 64 KiB total length πŸ™ˆ If you're on media that supports jumbo frames, we suggest defining a media adaptation envelope that lets you carry multiple smaller frames instead.

   +--------+------------------+---------------------------------------+
   | Abbrev |       Name       | Description                           |
   +--------+------------------+---------------------------------------+
   | T_ORG  | Vendor Specific  | Information specific to a vendor      |
   |        |   Information    | implementation (Section 3.3.2).       |
   |        |                  |                                       |
   | T_PAD  |     Padding      | Adds padding to a field (Section      |
   |        |                  | 3.3.1).                               |
   |        |                  |                                       |
   |  n/a   |   Experimental   | Experimental use.                     |
   +--------+------------------+---------------------------------------+

                        Table 1: Reserved TLV Types

Okay so the table is the VIP list πŸ‘‘ There are a few global TLV definitions that get reserved at every hierarchical context. The TLV types in the range 0x1000 - 0x1FFF are Reserved for Experimental Use πŸ§ͺ The TLV type T_ORG is also Reserved for Vendor Extensions (see Section 3.3.2), and T_PAD is used to optionally pad a field out to some desired alignment ✨

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |              Type             |            Length             |
   +---------------+---------------+---------------+---------------+

                    Figure 1: Type and Length encoding

The Length field holds the length of the Value field in octets. It does not count the Type and Length fields themselves πŸ’… The Length MAY be zero, so an empty value is totally allowed.

TLV structures are nestable, which means the Value field of one TLV structure can hold additional TLV structures inside it πŸͺ† The enclosing TLV structure is called the container of the enclosed TLV.

Type values are context dependent. Inside a TLV container, you can reuse earlier type values for new, context-dependent purposes 🌈


3.1. Overall Packet Format

Each CCNx Packet starts with the 8-byte fixed header (more on that in a sec), followed by a set of TLV fields. Those fields are optional hop-by-hop headers and the Packet Payload πŸ“¦

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |    Version    |  PacketType   |         PacketLength          |
   +---------------+---------------+---------------+---------------+
   |           PacketType-specific fields          | HeaderLength  |
   +---------------+---------------+---------------+---------------+
   / Optional hop-by-hop header TLVs                               /
   +---------------+---------------+---------------+---------------+
   / PacketPayload TLVs                                            /
   +---------------+---------------+---------------+---------------+

                      Figure 2: Overall Packet Format

The PacketPayload of a CCNx Packet is the protocol message itself πŸ’œ The Content Object Hash gets computed over the PacketPayload only, so the fixed and hop-by-hop headers are excluded, since those might change from hop to hop πŸ”„ Signed information or similarity hashes should not include any of the fixed or hop-by-hop headers. The PacketPayload should be self-sufficient in case the fixed and hop-by-hop headers get removed. See Message Hash (Section 3.4.3).

After the CCNx Message TLV, the PacketPayload may include optional Validation TLVs πŸ”

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   | CCNx Message TLV                                              /
   +---------------+---------------+---------------+---------------+
   / Optional CCNx ValidationAlgorithm TLV                         /
   +---------------+---------------+---------------+---------------+
   / Optional CCNx ValidationPayload TLV (ValidationAlg required)  /
   +---------------+---------------+---------------+---------------+

                       Figure 3: PacketPayload TLVs

After you throw away the fixed and hop-by-hop headers, what's left of the PacketPayload should be a valid protocol message. So the PacketPayload always starts with 4 bytes of type-length that say what the protocol message is (an Interest, a Content Object, or some other message type) and how long it is in total 🧾 Embedding a self-sufficient protocol data unit inside the fixed and hop-by-hop headers lets a network stack discard the headers and work only with the embedded message. It also decouples the PacketType field, which tells the packet how to be forwarded, from the PacketPayload 🚦

The range of bytes protected by the Validation includes the CCNx Message TLV and the ValidationAlgorithm TLV πŸ›‘οΈ

The ContentObjectHash begins with the CCNx Message TLV and runs to the tail of the CCNx Packet.


3.2. Fixed Headers

In Figure 2, the fixed header fields are:

  • Version: defines the version of the packet, which MUST be 1.
  • HeaderLength: The length of the fixed header (8 bytes) and hop-by-hop headers. The minimum value MUST be 8.
  • PacketType: describes forwarder actions to take on the packet.
  • PacketLength: Total octets of packet including all headers (fixed header plus hop-by-hop headers) and protocol message.
  • PacketType-specific Fields: specific PacketTypes define the use of these bits.

The PacketType field tells the forwarder how to process the packet 🧭 A Request Packet (Interest) has PacketType PT_INTEREST, a Response (Content Object) has PacketType PT_CONTENT, and an Interest Return has PacketType PT_RETURN.

HeaderLength is the number of octets from the start of the CCNx Packet (Version) to the end of the hop-by-hop headers. PacketLength is the number of octets from the start of the packet to the end of the packet. Both lengths have a minimum value of 8, which is the fixed header itself πŸ“

The PacketType-specific fields are reserved bits whose use depends on the PacketType. They're used for network-level signaling πŸ“‘

3.2.1. Interest Fixed Header

If the PacketType is PT_INTEREST, the packet should be forwarded following the Interest pipeline in Section 2.4.4 of [RFC8569] πŸƒβ€β™€οΈ For this type of packet, the Fixed Header includes a field for a HopLimit, plus Reserved and Flags fields. The Reserved field MUST be set to 0 in an Interest. There are currently no flags defined, so the Flags field MUST be set to 0 πŸ™…β€β™€οΈ

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |    Version    |  PT_INTEREST  |         PacketLength          |
   +---------------+---------------+---------------+---------------+
   |   HopLimit    |   Reserved    |     Flags     | HeaderLength  |
   +---------------+---------------+---------------+---------------+

                         Figure 4: Interest Header

3.2.1.1. Interest HopLimit

For an Interest message, the HopLimit is a counter that goes down by one at each hop 🦘 It limits how far an Interest can travel on the network. The node originating the Interest MAY put in any value up to the maximum of 255. Each node that receives an Interest with a HopLimit decrements the value upon reception. If the value is 0 after the decrement, the Interest MUST NOT be forwarded off the node πŸ›‘

It is an error to receive an Interest from a remote node with the HopLimit field set to 0 ❌

3.2.2. Content Object Fixed Header

If the PacketType is PT_CONTENT, the packet should be forwarded following the Content Object pipeline in Section 2.4.4 of [RFC8569] πŸ“¬ A Content Object defines a Flags field. However, there are currently no flags defined, so the Flags field must be set to 0.

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |    Version    |  PT_CONTENT   |         PacketLength          |
   +---------------+---------------+---------------+---------------+
   |            Reserved           |     Flags     | HeaderLength  |
   +---------------+---------------+---------------+---------------+

                      Figure 5: Content Object Header

3.2.3. Interest Return Fixed Header

If the PacketType is PT_RETURN, the packet should be processed following the Interest Return rules in Section 10 of [RFC8569] πŸ” This Interest Return message is basically the original Interest with two changes: the PacketType becomes PT_RETURN, and a ReturnCode goes into the ReturnCode field. Everything else is unchanged from the Interest packet. The whole point of this encoding is to keep the packet length the same, so no extra bytes are needed to send an Interest back to the previous hop πŸͺ„

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |    Version    |   PT_RETURN   |         PacketLength          |
   +---------------+---------------+---------------+---------------+
   |   HopLimit    |  ReturnCode   |     Flags     | HeaderLength  |
   +---------------+---------------+---------------+---------------+

                     Figure 6: Interest Return Header

3.2.3.1. Interest Return HopLimit

This is the original Interest's HopLimit, as it was received before the decrement at the node sending the Interest Return πŸ¦‹

3.2.3.2. Interest Return Flags

These are the original Flags as set in the Interest 🌸

3.2.3.3. Return Code πŸŽ€

okay so this bit is all about the Return Code! πŸ’… this section maps the Return Code name from [RFC8569] to the TLV symbolic name, and then Section 4.2 turns those symbolic names into numeric values 🧚. And the node that creates the Interest Return is the one that sets this field.

A return code of 0 MUST NOT be used, bestie πŸ™ˆ because it means the returning system didn't touch the Return Code field at all.

   +-------------------------------------+-----------------------------+
   |             Return Type             | Name in RFC 8569            |
   +-------------------------------------+-----------------------------+
   |          T_RETURN_NO_ROUTE          | No Route                    |
   |                                     |                             |
   |       T_RETURN_LIMIT_EXCEEDED       | Hop Limit Exceeded          |
   |                                     |                             |
   |        T_RETURN_NO_RESOURCES        | No Resources                |
   |                                     |                             |
   |         T_RETURN_PATH_ERROR         | Path Error                  |
   |                                     |                             |
   |         T_RETURN_PROHIBITED         | Prohibited                  |
   |                                     |                             |
   |          T_RETURN_CONGESTED         | Congested                   |
   |                                     |                             |
   |        T_RETURN_MTU_TOO_LARGE       | MTU too large               |
   |                                     |                             |
   | T_RETURN_UNSUPPORTED_HASH_RESTRICTI | Unsupported ContentObjectHa |
   |                  ON                 | shRestriction               |
   |                                     |                             |
   |     T_RETURN_MALFORMED_INTEREST     | Malformed Interest          |
   +-------------------------------------+-----------------------------+

                           Table 2: Return Codes

3.3. Global Formats 🌈

this section is where the global formats live! ✨ they're allowed to be nested inside other TLVs, so they're super flexible πŸ’–

3.3.1. Pad πŸ“

pad TLVs are for sources that like their data word-aligned. like, if you're padding 4-byte words, you'd use a 1-byte, 2-byte, or 3-byte Length. and for 8-byte words, you'd go with a (0, 1, 2, 3, 5, 6, 7)-byte Length πŸ’…

okay, one big rule: one MUST NOT pad inside a Name πŸ™…β€β™€οΈ everywhere else, a pad MAY be tucked in after any other TLV in the CCNx Message TLV or in the ValidationAlgorithm TLV. and fyi, we won't be showing optional Pad TLVs for the rest of the doc, so don't be confused 🫢

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |             T_PAD             |             Length            |
   +---------------+---------------+---------------+---------------+
   /                 variable-length pad MUST be zeros             /
   +---------------+---------------+---------------+---------------+

                          Figure 7: Pad Encoding

3.3.2. Organization-Specific TLVs 🏒

organization-specific TLVs (aka Vendor TLVs) MUST use the T_ORG type, no exceptions πŸ’œ the Length field covers the organization-specific info plus 3 extra bytes. the Value starts with a 3-byte organization number, which comes from the network byte order encoding of the IANA "Private Enterprise Numbers" registry [IANA-PEN], and then the organization-specific info follows.

a T_ORG MAY be used as a path segment in a Name. it gets treated just like any other path segment, so no special VIP treatment πŸ‘‘

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |             T_ORG             |     Length (3+value length)   |
   +---------------+---------------+---------------+---------------+
   |   PEN[0]      |    PEN[1]     |     PEN[2]    |               /
   +---------------+---------------+---------------+               +
   /                  Vendor Specific Value                        /
   +---------------+---------------+---------------+---------------+

                   Figure 8: Organization-Specific TLVs

3.3.3. Hash Format πŸ”

hash values show up in a bunch of fields throughout a packet πŸ¦‹ this TLV encoding usually gets embedded inside those fields to say which hash function was used and what its value is. quick heads up: the reserved TLV types are also reserved here for user-defined experimental functions πŸ§ͺ

the LENGTH field of the hash value MUST be less than or equal to the hash function length. if LENGTH is shorter than the full length, it's taken as the left LENGTH bytes of the hash function output. only specified truncations are allowed, not arbitrary ones, so no freestyling πŸ™…β€β™€οΈ

why nest it like this? ngl it's genius 🧠 it lets routers do a binary comparison of certain fields without needing to understand a brand new hash function. for example, the KeyIdRestriction gets bit-wise compared between an Interest's KeyIdRestriction field and a ContentObject's KeyId field. the outer field values stay the same no matter which hash function is used, so a router can still spot those fields and binary compare the hash TLV without knowing the specific hash. the alternative, like using T_KEYID_SHA512-256, would make every router keep an up-to-date parser, and supporting user-defined hash functions would explode the parsing state-space πŸ’€ nobody wants that.

a CCNx entity MUST support the hash type T_SHA-256. an entity MAY support the remaining hash types 🌸

                  +-----------+------------------------+
                  |   Abbrev  |    Lengths (octets)    |
                  +-----------+------------------------+
                  | T_SHA-256 |           32           |
                  |           |                        |
                  | T_SHA-512 |         64, 32         |
                  |           |                        |
                  |    n/a    | Experimental TLV types |
                  +-----------+------------------------+

                       Table 3: CCNx Hash Functions
                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |             T_FOO             |              36               |
   +---------------+---------------+---------------+---------------+
   |           T_SHA512            |               32              |
   +---------------+---------------+---------------+---------------+
   /                        32-byte hash value                     /
   +---------------+---------------+---------------+---------------+

                Figure 9: Example nesting inside type T_FOO

a Link is the tuple {Name, [KeyIdRestr], [ContentObjectHashRestr]}. it's a general encoding that shows up in two places: the payload of a Content Object with PayloadType = "Link", and a Content Object's KeyLink field. honestly, a Link is basically the body of an Interest, so it's giving familiar vibes ✨

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   / Mandatory CCNx Name                                           /
   +---------------+---------------+---------------+---------------+
   / Optional KeyIdRestriction                                     /
   +---------------+---------------+---------------+---------------+
   / Optional ContentObjectHashRestriction                         /
   +---------------+---------------+---------------+---------------+

                         Figure 10: Link Encoding

3.4. Hop-by-Hop TLV Headers πŸ¦‹

okay, hop-by-hop TLV headers are unordered, so their meaning MUST NOT be attached to their ordering πŸ™ƒ this document describes three of them:

   +-------------+--------------------+--------------------------------+
   |    Abbrev   |        Name        | Description                    |
   +-------------+--------------------+--------------------------------+
   |  T_INTLIFE  | Interest Lifetime  | The time an Interest should    |
   |             |  (Section 3.4.1)   | stay pending at an             |
   |             |                    | intermediate node.             |
   |             |                    |                                |
   | T_CACHETIME | Recommended Cache  | The Recommended Cache Time for |
   |             |   Time (Section    | Content Objects.               |
   |             |       3.4.2)       |                                |
   |             |                    |                                |
   |  T_MSGHASH  |    Message Hash    | A cryptographic hash (Section  |
   |             |  (Section 3.4.3)   | 3.3.3).                        |
   +-------------+--------------------+--------------------------------+

                     Table 4: Hop-by-Hop Header Types

more hop-by-hop headers are defined in higher level specifications, like the fragmentation specification 🧩

3.4.1. Interest Lifetime ⏳

the Interest Lifetime is how long an Interest should stay pending at an intermediate node ⏰ it's an unsigned integer in network byte order, expressed in milliseconds.

a value of 0 (encoded as 1 byte 0x00) means the Interest doesn't elicit a Content Object response. it should still be forwarded, but no reply is expected, and a forwarder could skip creating a PIT entry πŸŒ™

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------+---------------+---------------+---------------+
   |          T_INTLIFE            |             Length            |
   +---------------+---------------+---------------+---------------+
   /                                                               /
   /                      Lifetime (Length octets)                 /
   /                                                               /
   +---------------+---------------+---------------+---------------+

                   Figure 11: Interest Lifetime Encoding

Okay bestie, the Recommended Cache Time (RCT) is basically a hint about how long a Content Object is useful for. The content producer or an upstream node sets it, and the Content Store cache can use it as a guideline for how long to hang on to that object 🧚. It's just a suggestion, so the cache is totally allowed to ignore it πŸ™ˆ. ExpiryTime (see Section 3.6.2.2.2) is the one with real power. It beats the RCT, and it has to be obeyed πŸ’….

Since the RCT is an optional hop-by-hop header and it's not part of the signed message, a content producer can re-issue a Content Object that was already signed with a new RCT, and they don't need to re-sign it πŸ¦‹. An attacker changing the RCT doesn't do much harm either, because it's only a guideline 🌸.

The Recommended Cache Time is a millisecond timestamp. It's an unsigned integer in network byte order, and it says when the payload expires, counted as milliseconds since the epoch in UTC ⏰. It's a 64-bit field πŸŽ€.

                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|         T_CACHETIME           |               8               |
+---------------+---------------+---------------+---------------+
/                                                               /
/                    Recommended Cache Time                     /
/                                                               /
+---------------+---------------+---------------+---------------+

             Figure 12: Recommended Cache Time Encoding

3.4.3. Message Hash πŸ”₯

Okay, so within a trusted domain, an operator can work out the message hash at a border device and stick that value into the hop-by-hop headers of a message πŸ‘‘. An egress device should remove that value afterwards. The payoff is that intermediate devices in the domain can match against a ContentObjectHashRestriction without recalculating the hash at every hop 🫢.

The message hash is a cryptographic hash that runs from the start of the CCNx Message TLV to the end of the packet πŸ”. It gets matched against the ContentObjectHashRestriction (Section 3.6.2.1.2). The Message Hash can be longer than an Interest's restriction. If that happens, the device should use the left bytes of the Message Hash to check against the Interest's value πŸ’œ.

The Message Hash can only carry one hash type, and there can only be one Message Hash header πŸ“.

The Message Hash header is unprotected, so it's only really useful inside a trusted domain, like an operator's autonomous system. Don't trust it outside that bubble 😭.
                    1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|          T_MSGHASH            |         (length + 4)          |
+---------------+---------------+---------------+---------------+
|          hash type            |            length             |
+---------------+---------------+---------------+---------------+
/                           hash value                          /
+---------------+---------------+---------------+---------------+

                   Figure 13: Message Hash Header

3.5. Top-Level Types 🌈

The top-level TLV types below live at the outermost level of a CCNx Message TLV πŸ¦‹.

+----------------------+------------+-------------------------------+
|        Abbrev        |    Name    | Description                   |
+----------------------+------------+-------------------------------+
|      T_INTEREST      |  Interest  | An Interest MessageType.      |
|                      |  (Section  |                               |
|                      |    3.6)    |                               |
|                      |            |                               |
|       T_OBJECT       |  Content   | A Content Object MessageType  |
|                      |   Object   |                               |
|                      |  (Section  |                               |
|                      |    3.6)    |                               |
|                      |            |                               |
|   T_VALIDATION_ALG   | Validation | The method of message         |
|                      | Algorithm  | verification such as a        |
|                      |  (Section  | Message Integrity Check       |
|                      |  3.6.4.1)  | (MIC), Message Authentication |
|                      |            | Code (MAC), or cryptographic  |
|                      |            | signature.                    |
|                      |            |                               |
| T_VALIDATION_PAYLOAD | Validation | The validation output, such   |
|                      |  Payload   | as the CRC32C code or the RSA |
|                      |  (Section  | signature.                    |
|                      |  3.6.4.2)  |                               |
+----------------------+------------+-------------------------------+

                   Table 5: CCNx Top Level Types

3.6. CCNx Message TLV ✨

This is the format for the CCNx Message itself πŸ’…. The CCNx Message TLV is the chunk of the CCNx Packet that sits between the hop-by-hop headers and the Validation TLVs. The figure below expands on the "CCNx Message TLV" shown at the start of Section 3. The CCNx Message TLV starts with MessageType and runs through the optional Payload. Interest and Content Object messages both use the same general format, and MessageType is what tells them apart πŸ‘‘. The first enclosed TLV in a CCNx Message TLV is always the Name TLV, if one is present. After that come the optional Message TLVs and then an optional Payload TLV πŸŽ€.

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|         MessageType           |         MessageLength         |
+---------------+---------------+---------------+---------------+
/ Name TLV       (Type = T_NAME)                                /
+---------------+---------------+---------------+---------------+
/ Optional Message TLVs   (Various Types)                       /
+---------------+---------------+---------------+---------------+
/ Optional Payload TLV  (Type = T_PAYLOAD)                      /
+---------------+---------------+---------------+---------------+

                Figure 14: CCNx Message TLV Encoding
+-----------+---------------+---------------------------------------+
|   Abbrev  |      Name     | Description                           |
+-----------+---------------+---------------------------------------+
|   T_NAME  | Name (Section | The CCNx Name requested in an         |
|           |     3.6.1)    | Interest or published in a Content    |
|           |               | Object.                               |
|           |               |                                       |
| T_PAYLOAD |    Payload    | The message payload.                  |
|           |    (Section   |                                       |
|           |     3.6.3)    |                                       |
+-----------+---------------+---------------------------------------+

                   Table 6: CCNx Message TLV Types

3.6.1. Name πŸ¦‹

A Name is a TLV encoded sequence of segments 🧁. The table below lists the type values that fit these name segments. A Name MUST NOT include Pad TLVs, so no Pads allowed in there πŸ™…β€β™€οΈ.

As described in CCNx Semantics [RFC8569], using the CCNx URI [CCNxURI] notation, a T_NAME with zero length corresponds to "ccnx:/" (the default route) 🌸. The message grammar doesn't let the first name segment have zero length in a CCNx Message TLV Name. In the TLV encoding, "ccnx:/" maps to T_NAME with zero length ✨.

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|            T_NAME             |            Length             |
+---------------+---------------+---------------+---------------+
/ Name segment TLVs                                             /
+---------------+---------------+---------------+---------------+

                     Figure 15: Name Encoding
+---------------+-------------+-------------------------------------+
| Symbolic Name |     Name    | Description                         |
+---------------+-------------+-------------------------------------+
| T_NAMESEGMENT |     Name    | A generic name segment.             |
|               |   segment   |                                     |
|               |   (Section  |                                     |
|               |   3.6.1.1)  |                                     |
|               |             |                                     |
|     T_IPID    |   Interest  | An identifier that represents the   |
|               |  Payload ID | Interest Payload field. As an       |
|               |   (Section  | example, the Payload ID might be a  |
|               |   3.6.1.2)  | hash of the Interest Payload.  This |
|               |             | provides a way to differentiate     |
|               |             | between Interests based on their    |
|               |             | payloads without having to parse    |
|               |             | all the bytes of the payload        |
|               |             | itself, and instead using only this |
|               |             | Payload ID name segment.            |
|               |             |                                     |
|   T_APP:00 -  | Application | Application-specific payload in a   |
|   T_APP:4096  |  Components | name segment.  An application may   |
|               |   (Section  | apply its own semantics to the 4096 |
|               |   3.6.1.1)  | reserved types.                     |
+---------------+-------------+-------------------------------------+

                   Table 7: CCNx Name Types

3.6.1.1. Name Segments ✨

4096 special application payload name segments are allocated πŸŽ€ These carry application semantics, so the vibe is that they mean something specific to the app. A good convention is to put the application's identity in the name before you use these segments. Super organized, bestie πŸ’…

For example, a name like ccnx:/foo/bar/hi would be encoded as:

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|            (T_NAME)           |           0x14 (20)           |
+---------------+---------------+---------------+---------------+
|        (T_NAME_SEGMENT)       |           0x03 (3)            |
+---------------+---------------+---------------+---------------+
|       f                o               o      |(T_NAME_SEGMENT)
+---------------+---------------+---------------+---------------+
|               |            0x03 (3)           |       b       |
+---------------+---------------+---------------+---------------+
|      a                r       |           (T_NAME_SEGMENT)    |
+---------------+---------------+---------------+---------------+
|           0x02 (2)            |       h       |       i       |
+---------------+---------------+---------------+---------------+

Figure 16: Name Encoding Example 🧚

3.6.1.2. Interest Payload ID 🌸

The InterestPayloadID is a name segment that the origin of an Interest creates to represent the Interest Payload. It's how Interests get properly multiplexed by name when they have different payloads. A common move is to use a hash of the Interest Payload as the InterestPayloadID πŸ”₯

As part of the Value of the TLV, the InterestPayloadID holds a one-octet identifier for the method used to create it, followed by a variable-length octet string. An implementation is not required to implement any of the methods to receive an Interest. Honestly, the InterestPayloadID can just be treated as an opaque octet string when you're multiplexing Interests with different payloads. Only a device creating an InterestPayloadID name segment, or a device verifying one, needs to implement the algorithms πŸ™ˆ

It uses the encoding of hash values specified in Section 3.3.3.

In normal operations, we recommend displaying the InterestPayloadID as an opaque octet string in a CCNx URI, since that's the common denominator for implementation parsing πŸ’–

The InterestPayloadID, even if it's a hash, should not convey any security context. Like, not me being paranoid here 😭 If a system needs to confirm that a specific entity created the InterestPayload, it should use a cryptographic signature on the Interest via the ValidationAlgorithm and ValidationPayload, or use its own methods inside the Interest Payload.

3.6.2. Message TLVs πŸ’œ

Each message type (Interest or Content Object) is associated with a set of optional Message TLVs. Additional specification documents may extend the types associated with each. Main character expansion packs, iykyk ✨

3.6.2.1. Interest Message TLVs πŸ¦‹

There are two Message TLVs currently associated with an Interest message: the KeyIdRestriction selector and the ContentObjectHashRestr selector. They're used to narrow down the universe of acceptable Content Objects that would satisfy the Interest. Think of them as the bouncers of the Interest club πŸ’…

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|         MessageType           |         MessageLength         |
+---------------+---------------+---------------+---------------+
| Name TLV                                                      |
+---------------+---------------+---------------+---------------+
/ Optional KeyIdRestriction TLV                                 /
+---------------------------------------------------------------+
/ Optional ContentObjectHashRestriction TLV                     /
+---------------------------------------------------------------+

Figure 17: Interest Message TLVs

+----------------+------------------------------+-------------------+
|     Abbrev     |             Name             | Description       |
+----------------+------------------------------+-------------------+
|  T_KEYIDRESTR  |  KeyIdRestriction (Section   | A representation  |
|                |          3.6.2.1.1)          | (as per Section   |
|                |                              | 3.3.3) of the     |
|                |                              | KeyId             |
|                |                              |                   |
| T_OBJHASHRESTR | ContentObjectHashRestriction | A representation  |
|                |     (Section 3.6.2.1.2)      | (as per Section   |
|                |                              | 3.3.3) of the     |
|                |                              | hash of the       |
|                |                              | specific Content  |
|                |                              | Object that would |
|                |                              | satisfy the       |
|                |                              | Interest.         |
+----------------+------------------------------+-------------------+

Table 8: CCNx Interest Message TLV Types πŸ“

3.6.2.1.1. KeyIdRestriction πŸ”‘

An Interest MAY include a KeyIdRestriction selector. This makes sure that only Content Objects with matching KeyIds will satisfy the Interest. See Section 3.6.4.1.4.1 for the format of a KeyId.

3.6.2.1.2. ContentObjectHashRestriction 🧷

An Interest MAY contain a ContentObjectHashRestriction selector. This is the hash of the Content Object, the self-certifying name restriction that must be verified in the network, if an Interest carried this restriction (see Message Hash (Section 3.4.3)). The LENGTH MUST be from one of the allowed values for that hash (see Section 3.3.3).

The ContentObjectHashRestriction SHOULD be of type T_SHA-256 and of length 32 bytes. 🌈

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|        T_OBJHASHRESTR         |           (LENGTH+4)          |
+---------------+---------------+---------------+---------------+
|           hash type           |             LENGTH            |
+---------------+---------------+---------------+---------------+
/                     LENGTH octets of hash                     /
+---------------+---------------+---------------+---------------+

Figure 18: ContentObjectHashRestriction Encoding

3.6.2.2. Content Object Message TLVs 🌟

The following message TLVs are currently defined for Content Objects: PayloadType (optional) and ExpiryTime (optional).

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|         MessageType           |         MessageLength         |
+---------------+---------------+---------------+---------------+
| Name TLV                                                      |
+---------------+---------------+---------------+---------------+
/ Optional PayloadType TLV                                      /
+---------------------------------------------------------------+
/ Optional ExpiryTime TLV                                       /
+---------------------------------------------------------------+

Figure 19: Content Object Message TLVs

+-------------+-------------+---------------------------------------+
|    Abbrev   |     Name    | Description                           |
+-------------+-------------+---------------------------------------+
| T_PAYLDTYPE | PayloadType | Indicates the type of Payload         |
|             |   (Section  | contents.                             |
|             |  3.6.2.2.1) |                                       |
|             |             |                                       |
|   T_EXPIRY  |  ExpiryTime | The time at which the Payload         |
|             |   (Section  | expires, as expressed in the number   |
|             |  3.6.2.2.2) | of milliseconds since the epoch in    |
|             |             | UTC.  If missing, Content Object may  |
|             |             | be used as long as desired.           |
+-------------+-------------+---------------------------------------+

Table 9: CCNx Content Object Message TLV Types 🎁

3.6.2.2.1. PayloadType πŸ“¦

The PayloadType is an octet that represents the general type of the Payload TLV. There are three flavors:

  • T_PAYLOADTYPE_DATA: Data (possibly encrypted)
  • T_PAYLOADTYPE_KEY: Key
  • T_PAYLOADTYPE_LINK: Link

The Data type means the Payload of the ContentObject is opaque application bytes. The Key type means the Payload is a DER-encoded public key. The Link type means the Payload is one or more Links (Section 3.3.4). If this field is missing, a Data type is assumed. 🫢

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|            T_PAYLDTYPE        |               1               |
+---------------+---------------+---------------+---------------+
|  PayloadType  |
+---------------+

Figure 20: PayloadType Encoding

3.6.2.2.2. ExpiryTime ⏰

The ExpiryTime is the time at which the Payload expires, expressed as a timestamp holding the number of milliseconds since the epoch in UTC. It's a network byte order unsigned integer in a 64-bit field. A cache or end system should not respond with a Content Object past its ExpiryTime. Routers forwarding a Content Object do not need to check the ExpiryTime. If the ExpiryTime field is missing, the Content Object has no expressed expiration, and a cache or end system may use it for as long as desired πŸ¦‹

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|           T_EXPIRY            |               8               |
+---------------+---------------+---------------+---------------+
/                          ExpiryTime                           /
/                                                               /
+---------------+---------------+---------------+---------------+

Figure 21: ExpiryTime encoding

3.6.3. Payload 🍰

The Payload TLV contains the content of the packet. It MAY be of zero length. If a packet doesn't have any payload, this field SHOULD be omitted, rather than being of zero length. Clean encoding, no cap πŸ’…

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|           T_PAYLOAD           |            Length             |
+---------------+---------------+---------------+---------------+
/                        Payload Contents                       /
+---------------+---------------+---------------+---------------+

Figure 22: Payload Encoding

3.6.4. Validation ✨

okay bestie, so both Interests and Content Objects can carry info about how to validate the CCNx Message πŸ” this info lives in two TLVs: the ValidationAlgorithm TLV and the ValidationPayload TLV. the ValidationAlgorithm TLV says which mechanism to use to verify the message (think a Message Integrity Check (MIC), a Message Authentication Code (MAC), or a cryptographic signature πŸ’…). the ValidationPayload TLV holds the actual validation output, like the CRC32C code or the RSA signature πŸ¦‹

an Interest would most likely only use a MIC type of validation, so a CRC, checksum, or digest 🌸

3.6.4.1. Validation Algorithm

the ValidationAlgorithm is a set of nested TLVs with everything you need to verify the message 🧚 the outermost container has type = T_VALIDATION_ALG. the first nested TLV defines the specific type of validation to run on the message. that type is named by the "ValidationType" (see the figure and table below) πŸ‘‘ inside that container you'll find the TLVs for any ValidationType-dependent data, like a Key Id, a Key Locator, etc.

complete examples of several types are in Section 3.6.4.1.5 πŸŽ€

                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|       T_VALIDATION_ALG        |      ValidationAlgLength      |
+---------------+---------------+---------------+---------------+
|        ValidationType         |            Length             |
+---------------+---------------+---------------+---------------+
/ ValidationType-dependent data                                 /
+---------------+---------------+---------------+---------------+

Figure 23: Validation Algorithm Encoding

+-----------------+---------------+---------------------------------+
|      Abbrev     |      Name     | Description                     |
+-----------------+---------------+---------------------------------+
|     T_CRC32C    |     CRC32C    | Castagnoli CRC32 (iSCSI, ext4,  |
|                 |    (Section   | etc.) with normal form          |
|                 |   3.6.4.1.1)  | polynomial 0x1EDC6F41.          |
|                 |               |                                 |
|  T_HMAC-SHA256  |  HMAC-SHA256  | HMAC (RFC 2104) using SHA256    |
|                 |    (Section   | hash.                           |
|                 |   3.6.4.1.2)  |                                 |
|                 |               |                                 |
|   T_RSA-SHA256  |   RSA-SHA256  | RSA public-key signature using  |
|                 |    (Section   | SHA256 digest.                  |
|                 |   3.6.4.1.3)  |                                 |
|                 |               |                                 |
| T_EC-SECP-256K1 |   SECP-256K1  | Elliptic Curve signature with   |
|                 |    (Section   | SECP-256K1 parameters (see      |
|                 |   3.6.4.1.3)  | [ECC]).                         |
|                 |               |                                 |
| T_EC-SECP-384R1 |   SECP-384R1  | Elliptic Curve signature with   |
|                 |    (Section   | SECP-384R1 parameters (see      |
|                 |   3.6.4.1.3)  | [ECC]).                         |
+-----------------+---------------+---------------------------------+

Table 10: CCNx Validation Types

3.6.4.1.1. Message Integrity Checks

MICs don't need any extra data to do the verification πŸ™ˆ CRC32C is a great example, since it has a zero-length value ✨

3.6.4.1.2. Message Authentication Codes

MACs are useful for communication between two trusting parties who have already shared secret keys 🀝 HMAC is an example of this. a MAC uses the KeyId field to figure out which shared secret is in use πŸ”‘ what the KeyId means is specific to the two parties involved, and it could be as simple as an integer used to number the keys πŸ”’ if a new MAC needs an additional field, like an Initialization Vector, that field would need to be defined as part of the updated specification πŸ“œ

3.6.4.1.3. Signature

Signature type Validators specify a digest mechanism and a signing algorithm to verify the message πŸ’– examples include an RSA signature on a SHA256 digest, or an Elliptic Curve signature with SECP-256K1 parameters, etc. these Validators need a KeyId and a way to locate the publisher's public key (a KeyLocator), and optionally a PublicKey or Certificate or KeyLink πŸͺͺ

3.6.4.1.4. Validation-Dependent Data

different Validation Algorithms need access to different pieces of data inside the ValidationAlgorithm TLV 🌈 as we said above, Key Ids, Key Locators, Public Keys, Certificates, Links, and Key Names all play a role in different Validation Algorithms πŸ’… there can be any number of Validation-Dependent Data containers in one Validation Algorithm TLV ✨

here's the table of CCNx ValidationType-dependent data types:

+-------------+-----------------+-----------------------------------+
|    Abbrev   |       Name      | Description                       |
+-------------+-----------------+-----------------------------------+
|   T_KEYID   |   SignerKeyId   | An identifier of the shared       |
|             |     (Section    | secret or public key associated   |
|             |   3.6.4.1.4.1)  | with a MAC or Signature.          |
|             |                 |                                   |
| T_PUBLICKEY |    Public Key   | DER-encoded public key.           |
|             |     (Section    |                                   |
|             |   3.6.4.1.4.2)  |                                   |
|             |                 |                                   |
|    T_CERT   |   Certificate   | DER-encoded X.509 certificate.    |
|             |     (Section    |                                   |
|             |   3.6.4.1.4.3)  |                                   |
|             |                 |                                   |
|  T_KEYLINK  |     KeyLink     | A CCNx Link object.               |
|             |     (Section    |                                   |
|             |   3.6.4.1.4.4)  |                                   |
|             |                 |                                   |
|  T_SIGTIME  |  SignatureTime  | A millisecond timestamp           |
|             |     (Section    | indicating the time when the      |
|             |   3.6.4.1.4.5)  | signature was created.            |
+-------------+-----------------+-----------------------------------+

Table 11: CCNx Validation-Dependent Data Types

3.6.4.1.4.1. KeyId

the KeyId for a signature is the publisher key identifier πŸ†” it's kind of like a Subject Key Identifier from X.509 (see Section 4.2.1.2 of [RFC5280]) πŸŽ€ it should be derived from the key used to sign, such as from the SHA-256 hash of the key. it applies to public and private key systems, and to symmetric key systems too πŸ”

the KeyId is represented using the hash format in Section 3.3.3. if an application protocol uses a non-hash identifier, it should use one of the reserved values 🧩

                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|            T_KEYID            |            LENGTH+4           |
+---------------+---------------+---------------+---------------+
|          <hash type>          |             LENGTH            |
+---------------+---------------+---------------+---------------+
/                     LENGTH octets of hash                     /
+---------------+---------------+---------------+---------------+

Figure 24: KeyId Encoding

3.6.4.1.4.2. Public Key

a Public Key is a DER-encoded Subject Public Key Info block, just like the one in an X.509 certificate 🌸

                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|          T_PUBLICKEY          |            Length             |
+---------------+---------------+---------------+---------------+
/                Public Key (DER-encoded SPKI)                  /
+---------------+---------------+---------------+---------------+

Figure 25: Public Key Encoding

3.6.4.1.4.3. Certificate

a Certificate is a DER-encoded X.509 certificate πŸ“œ the KeyId (Section 3.6.4.1.4.1) is derived from this encoding πŸ¦‹

                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|            T_CERT             |            Length             |
+---------------+---------------+---------------+---------------+
/                 Certificate (DER-encoded X.509)               /
+---------------+---------------+---------------+---------------+

Figure 26: Certificate Encoding

a KeyLink type KeyLocator is a Link πŸ”—

the KeyLink ContentObjectHashRestr, if included, is the digest of the Content Object identified by KeyLink, not the digest of the public key πŸ‘€ likewise, the KeyIdRestr of the KeyLink is the KeyId of the ContentObject, not necessarily of the wrapped key πŸ™ƒ

                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+-------------------------------+
|          T_KEYLINK            |            Length             |
+---------------+---------------+-------------------------------+
/ Link                                                          /
+---------------------------------------------------------------+

Figure 27: KeyLink Encoding

3.6.4.1.4.5. SignatureTime

the SignatureTime is a millisecond timestamp for when a signature was created ⏰ the signer sets it to the current time when making a signature. a verifier may use this time to check whether the signature was made during a key's validity period, or whether it happened in a reasonable sequence with other related signatures πŸ•°οΈ the SignatureTime has nothing to do with any time tied to the actual CCNx Message, which could have been created long before the signature 🫢 the default behavior is to always include a SignatureTime when making an authenticated message (e.g., HMAC or RSA) πŸ’œ

SignatureTime is an unsigned integer in network byte order that says when the signature was created (as the number of milliseconds since the epoch in UTC). it's a fixed 64-bit field πŸ”’

                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+-------------------------------+
|           T_SIGTIME           |               8               |
+---------------+---------------+-------------------------------+
/                         SignatureTime                         /
+---------------------------------------------------------------+

Figure 28: SignatureTime Encoding

3.6.4.1.5. Validation Examples

okay bestie, let's look at some real examples πŸ¦‹ first up is a MIC-type validation, so here's what the CRC32C encoding looks like πŸ’–

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|      T_VALIDATION_ALG         |               4               |
+---------------+---------------+---------------+---------------+
|            T_CRC32C           |               0               |
+---------------+---------------+---------------+---------------+

                 Figure 29: CRC32C Encoding Example

next, a MAC-type validation 🌸 this one is an HMAC using a SHA256 hash, and it's giving clean structure ✨

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|       T_VALIDATION_ALG        |               40              |
+---------------+---------------+---------------+---------------+
|        T_HMAC-SHA256          |               36              |
+---------------+---------------+---------------+---------------+
|             T_KEYID           |               32              |
+---------------+---------------+---------------+---------------+
/                            KeyId                              /
/---------------+---------------+-------------------------------+

               Figure 30: HMAC-SHA256 Encoding Example

and last but not least, the Signature-type validation πŸ‘‘ this is an RSA public-key signature using a SHA256 digest and Public Key, and the vibes are immaculate πŸ”₯

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|       T_VALIDATION_ALG        |   44 octets + Variable Length |
+---------------+---------------+---------------+---------------+
|          T_RSA-SHA256         |   40 octets + Variable Length |
+---------------+---------------+---------------+---------------+
|             T_KEYID           |               32              |
+---------------+---------------+---------------+---------------+
/                            KeyId                              /
/---------------+---------------+-------------------------------+
|          T_PUBLICKEY          |  Variable Length (~160 octets)|
+---------------+---------------+---------------+---------------+
/                Public Key (DER-encoded SPKI)                  /
+---------------+---------------+---------------+---------------+

               Figure 31: RSA-SHA256 Encoding Example

3.6.4.2. Validation Payload

the payload is where the actual validation output lives 🧚 it's got a type, a length, and then type-dependent data

                    1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
|     T_VALIDATION_PAYLOAD      |  ValidationPayloadLength      |
+---------------+---------------+---------------+---------------+
/ Type-dependent data                                           /
+---------------+---------------+---------------+---------------+

              Figure 32: Validation Payload Encoding

the ValidationPayload holds the validation output, like the CRC32C code or the RSA signature πŸ’œ


4. IANA Considerations ✨

okay so this section is all about the registries, meaning the places where each kind of CCNx protocol value gets officially listed πŸ“‹ every type registry can grow by expanding the type space, which is just allocating and reserving new types 🌈 and as per [RFC8126], this section sets up the "Content-Centric Networking (CCNx)" registry plus a bunch of subregistries πŸ’…

4.1. Packet Type Registry

IANA made the "CCNx Packet Types" registry and handed out the packet types below πŸŽ€ the registration procedure is RFC Required, the Type value is 1 octet, and the range is 0x00-0xFF.

      +------+-------------+----------------------------------+
      | Type |     Name    |            Reference             |
      +------+-------------+----------------------------------+
      | 0x00 | PT_INTEREST | Fixed Header Types (Section 3.2) |
      |      |             |                                  |
      | 0x01 |  PT_CONTENT | Fixed Header Types (Section 3.2) |
      |      |             |                                  |
      | 0x02 |  PT_RETURN  | Fixed Header Types (Section 3.2) |
      +------+-------------+----------------------------------+

                            Packet Types

4.2. Interest Return Code Registry

IANA made the "CCNx Interest Return Code Types" registry and allocated the Interest Return code types below πŸ“ the registration procedure is Specification Required, the Type value is 1 octet, and the range is 0x00-0xFF.

+------+---------------------------------------+--------------------+
| Type |                  Name                 |     Reference      |
+------+---------------------------------------+--------------------+
| 0x00 |                Reserved               |                    |
|      |                                       |                    |
| 0x01 |           T_RETURN_NO_ROUTE           | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x02 |        T_RETURN_LIMIT_EXCEEDED        | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x03 |         T_RETURN_NO_RESOURCES         | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x04 |          T_RETURN_PATH_ERROR          | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x05 |          T_RETURN_PROHIBITED          | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x06 |           T_RETURN_CONGESTED          | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x07 |         T_RETURN_MTU_TOO_LARGE        | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x08 | T_RETURN_UNSUPPORTED_HASH_RESTRICTION | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
|      |                                       |                    |
| 0x09 |      T_RETURN_MALFORMED_INTEREST      | Fixed Header Types |
|      |                                       | (Section 3.2.3.3)  |
+------+---------------------------------------+--------------------+

                      CCNx Interest Return Types

4.3. Hop-by-Hop Type Registry

IANA made the "CCNx Hop-by-Hop Types" registry and allocated the hop-by-hop types below 🧚 the registration procedure is RFC Required, the Type value is 2 octets, and the range is 0x0000-0xFFFF.

+---------------+-------------+-------------------------------------+
|      Type     |     Name    |              Reference              |
+---------------+-------------+-------------------------------------+
|     0x0000    |   Reserved  |                                     |
|               |             |                                     |
|     0x0001    |  T_INTLIFE  |   Hop-by-hop TLV headers (Section   |
|               |             |                 3.4)                |
|               |             |                                     |
|     0x0002    | T_CACHETIME |   Hop-by-hop TLV headers (Section   |
|               |             |                 3.4)                |
|               |             |                                     |
|     0x0003    |  T_MSGHASH  |   Hop-by-hop TLV headers (Section   |
|               |             |                 3.4)                |
|               |             |                                     |
|    0x0004 -   |   Reserved  |                                     |
|     0x0007    |             |                                     |
|               |             |                                     |
|     0x0FFE    |    T_PAD    |         Pad (Section 3.3.1)         |
|               |             |                                     |
|     0x0FFF    |    T_ORG    | Organization-Specific TLVs (Section |
|               |             |                3.3.2)               |
|               |             |                                     |
| 0x1000-0x1FFF |   Reserved  |     Experimental Use (Section 3)    |
+---------------+-------------+-------------------------------------+

                       CCNx Hop-by-Hop Types

4.4. Top-Level Type Registry

IANA made the "CCNx Top-Level Types" registry and allocated the top-level types below 🌟 the registration procedure is RFC Required, the Type value is 2 octets, and the range is 0x0000-0xFFFF.

  +--------+----------------------+-------------------------------+
  |  Type  |         Name         |           Reference           |
  +--------+----------------------+-------------------------------+
  | 0x0000 |       Reserved       |                               |
  |        |                      |                               |
  | 0x0001 |      T_INTEREST      | Top-Level Types (Section 3.5) |
  |        |                      |                               |
  | 0x0002 |       T_OBJECT       | Top-Level Types (Section 3.5) |
  |        |                      |                               |
  | 0x0003 |   T_VALIDATION_ALG   | Top-Level Types (Section 3.5) |
  |        |                      |                               |
  | 0x0004 | T_VALIDATION_PAYLOAD | Top-Level Types (Section 3.5) |
  +--------+----------------------+-------------------------------+

                       CCNx Top-Level Types

4.5. Name Segment Type Registry ✨

okay so IANA made a registry called "CCNx Name Segment Types" πŸŽ€ and handed out the name segment types listed below. The registration procedure is Specification Required, the Type value is 2 octets, and the range is 0x0000-0xFFFF πŸ’–

   +--------------+------------------+---------------------------------+
   |     Type     |       Name       |            Reference            |
   +--------------+------------------+---------------------------------+
   |    0x0000    |     Reserved     |                                 |
   |              |                  |                                 |
   |    0x0001    |  T_NAMESEGMENT   |       Name (Section 3.6.1)      |
   |              |                  |                                 |
   |    0x0002    |      T_IPID      |       Name (Section 3.6.1)      |
   |              |                  |                                 |
   |   0x0010 -   |     Reserved     |             RFC 8609            |
   |    0x0013    |                  |                                 |
   |              |                  |                                 |
   |    0x0FFF    |      T_ORG       |    Organization-Specific TLVs   |
   |              |                  |         (Section 3.3.2)         |
   |              |                  |                                 |
   |   0x1000 -   |    T_APP:00 -    | Application Components (Section |
   |    0x1FFF    |    T_APP:4096    |              3.6.1)             |
   +--------------+------------------+---------------------------------+

                          CCNx Name Segment Types

4.6. Message Type Registry πŸ¦‹

this one's the "CCNx Message Types" registry 🌸 IANA registered the message segment types below. The registration procedure is RFC Required, the Type value is 2 octets, and the range is 0x0000-0xFFFF. Slay the table πŸ’…

   +---------------+----------------+----------------------------------+
   |      Type     |      Name      |            Reference             |
   +---------------+----------------+----------------------------------+
   |     0x0000    |     T_NAME     |   Message Types (Section 3.6)    |
   |               |                |                                  |
   |     0x0001    |   T_PAYLOAD    |   Message Types (Section 3.6)    |
   |               |                |                                  |
   |     0x0002    |  T_KEYIDRESTR  |   Message Types (Section 3.6)    |
   |               |                |                                  |
   |     0x0003    | T_OBJHASHRESTR |   Message Types (Section 3.6)    |
   |               |                |                                  |
   |     0x0005    |  T_PAYLDTYPE   |   Content Object Message Types   |
   |               |                |        (Section 3.6.2.2)         |
   |               |                |                                  |
   |     0x0006    |    T_EXPIRY    |   Content Object Message Types   |
   |               |                |        (Section 3.6.2.2)         |
   |               |                |                                  |
   |    0x0007 -   |    Reserved    |             RFC 8609             |
   |     0x000C    |                |                                  |
   |               |                |                                  |
   |     0x0FFE    |     T_PAD      |       Pad (Section 3.3.1)        |
   |               |                |                                  |
   |     0x0FFF    |     T_ORG      |    Organization-Specific TLVs    |
   |               |                |         (Section 3.3.2)          |
   |               |                |                                  |
   | 0x1000-0x1FFF |    Reserved    |   Experimental Use (Section 3)   |
   +---------------+----------------+----------------------------------+

                            CCNx Message Types

4.7. Payload Type Registry πŸ’œ

IANA created the "CCNx Payload Types" registry and allocated the payload types below ✨ The registration procedure is Specification Required, the Type value is 1 octet, and the range is 0x00-0xFF.

     +------+--------------------+-----------------------------------+
     | Type |        Name        |             Reference             |
     +------+--------------------+-----------------------------------+
     | 0x00 | T_PAYLOADTYPE_DATA | Payload Types (Section 3.6.2.2.1) |
     |      |                    |                                   |
     | 0x01 | T_PAYLOADTYPE_KEY  | Payload Types (Section 3.6.2.2.1) |
     |      |                    |                                   |
     | 0x02 | T_PAYLOADTYPE_LINK | Payload Types (Section 3.6.2.2.1) |
     +------+--------------------+-----------------------------------+

                            CCNx Payload Types

4.8. Validation Algorithm Type Registry πŸ”₯

the "CCNx Validation Algorithm Types" registry is the one where IANA allocated the validation algorithm types below 🧚 The registration procedure is Specification Required, the Type value is 2 octets, and the range is 0x0000-0xFFFF.

   +---------------+-----------------+---------------------------------+
   |      Type     |       Name      |            Reference            |
   +---------------+-----------------+---------------------------------+
   |     0x0000    |     Reserved    |                                 |
   |               |                 |                                 |
   |     0x0002    |     T_CRC32C    |  Validation Algorithm (Section  |
   |               |                 |             3.6.4.1)            |
   |               |                 |                                 |
   |     0x0004    |  T_HMAC-SHA256  |  Validation Algorithm (Section  |
   |               |                 |             3.6.4.1)            |
   |               |                 |                                 |
   |     0x0005    |   T_RSA-SHA256  |  Validation Algorithm (Section  |
   |               |                 |             3.6.4.1)            |
   |               |                 |                                 |
   |     0x0006    | T_EC-SECP-256K1 |  Validation Algorithm (Section  |
   |               |                 |             3.6.4.1)            |
   |               |                 |                                 |
   |     0x0007    | T_EC-SECP-384R1 |  Validation Algorithm (Section  |
   |               |                 |             3.6.4.1)            |
   |               |                 |                                 |
   |     0x0FFE    |      T_PAD      |       Pad (Section 3.3.1)       |
   |               |                 |                                 |
   |     0x0FFF    |      T_ORG      |    Organization-Specific TLVs   |
   |               |                 |         (Section 3.3.2)         |
   |               |                 |                                 |
   | 0x1000-0x1FFF |     Reserved    |   Experimental Use (Section 3)  |
   +---------------+-----------------+---------------------------------+

                      CCNx Validation Algorithm Types

4.9. Validation-Dependent Data Type Registry 🌈

IANA made the "CCNx Validation-Dependent Data Types" registry and allocated the validation-dependent data types below 🫢 The registration procedure is RFC Required, the Type value is 2 octets, and the range is 0x0000-0xFFFF. Most of these point back to Section 3.6.4.1.4, so go check that if you want the full story πŸ‘‘

   +---------------+----------------+----------------------------------+
   |      Type     |      Name      |            Reference             |
   +---------------+----------------+----------------------------------+
   |     0x0000    |    Reserved    |                                  |
   |               |                |                                  |
   |     0x0009    |    T_KEYID     |    Validation-Dependent Data     |
   |               |                |       (Section 3.6.4.1.4)        |
   |               |                |                                  |
   |     0x000A    | T_PUBLICKEYLOC |    Validation-Dependent Data     |
   |               |                |       (Section 3.6.4.1.4)        |
   |               |                |                                  |
   |     0x000B    |  T_PUBLICKEY   |    Validation-Dependent Data     |
   |               |                |       (Section 3.6.4.1.4)        |
   |               |                |                                  |
   |     0x000C    |     T_CERT     |    Validation-Dependent Data     |
   |               |                |       (Section 3.6.4.1.4)        |
   |               |                |                                  |
   |     0x000D    |     T_LINK     |    Validation-Dependent Data     |
   |               |                |       (Section 3.6.4.1.4)        |
   |               |                |                                  |
   |     0x000E    |   T_KEYLINK    |    Validation-Dependent Data     |
   |               |                |       (Section 3.6.4.1.4)        |
   |               |                |                                  |
   |     0x000F    |   T_SIGTIME    |    Validation-Dependent Data     |
   |               |                |       (Section 3.6.4.1.4)        |
   |               |                |                                  |
   |     0x0FFF    |     T_ORG      |    Organization-Specific TLVs    |
   |               |                |         (Section 3.3.2)          |
   |               |                |                                  |
   | 0x1000-0x1FFF |    Reserved    |   Experimental Use (Section 3)   |
   +---------------+----------------+----------------------------------+

                   CCNx Validation-Dependent Data Types

4.10. Hash Function Type Registry πŸ“

last one in this batch! IANA created the "CCNx Hash Function Types" registry and allocated the hash function types below πŸ’… The registration procedure is Specification Required, the Type value is 2 octets, and the range is 0x0000-0xFFFF.

   +---------------+-----------+---------------------------------------+
   |      Type     |    Name   |               Reference               |
   +---------------+-----------+---------------------------------------+
   |     0x0000    |  Reserved |                                       |
   |               |           |                                       |
   |     0x0001    | T_SHA-256 |      Hash Format (Section 3.3.3)      |
   |               |           |                                       |
   |     0x0002    | T_SHA-512 |      Hash Format (Section 3.3.3)      |
   |               |           |                                       |
   |     0x0FFF    |   T_ORG   |  Organization-Specific TLVs (Section  |
   |               |           |                 3.3.2)                |
   |               |           |                                       |
   | 0x1000-0x1FFF |  Reserved |      Experimental Use (Section 3)     |
   +---------------+-----------+---------------------------------------+

                         CCNx Hash Function Types

5. Security Considerations ✨

okay bestie, buckle up because this section is LONG and it's giving "everything you need to know before you ship" πŸ’…πŸ”₯. the CCNx protocol is a Layer 3 network protocol, and it can also run as an overlay on top of other transports like UDP or tunnels πŸ¦‹. it has built-in support for message authentication using a signature (like RSA or elliptic curve) or a Message Authentication Code (like HMAC) πŸ”. if you don't want an authenticator, you can use a Message Integrity Check instead (like SHA or CRC) ✨. CCNx does NOT specify an encryption envelope, so that job gets handed off to a higher-layer protocol (like Encrypted Sessions in CCNx [esic]) πŸŽ€

the CCNx Packet format lets you attach MICs (like SHA-256 or CRC), MACs (like HMAC), and Signatures (like RSA or ECDSA) to all packet types πŸ’–. here's the tea: Interest packets can be sent whenever, so an application should be really careful about when it picks a given ValidationAlgorithm in an Interest πŸ™ˆ. avoiding DoS attacks is literally the whole point ngl 😭. MICs are cheap and can be used whenever, but MACs and Signatures are more expensive, and using them carelessly could open up a computational DoS attack surface πŸ’€. applications should use an explicit protocol to guide how they use packet signatures 🧚. as a general guideline, an application might use a MIC on an Interest to detect packets that got corrupted by accident πŸ“. if you want to actually secure an Interest, you should consider an encrypted wrapper plus a protocol that prevents replay attacks, especially if the Interest is being used as an actuator ⚠️. just slapping an authentication code or signature on an Interest does NOT make it secure, periodt πŸ™…β€β™€οΈ. there are several examples in the literature on securing ICN-style messaging [mobile] [ace] πŸ“š

as a Layer 3 protocol, this document doesn't describe how you get keys or how you decide to trust them πŸ”‘. the CCNx content object can include a public key embedded in the object, or use the PublicKeyLocator field to point at a public key (or public-key certificate) that authenticates the message 🫢. one key exchange spec is CCNxKE [ccnxke] [mobile], which is similar to the TLS 1.3 key exchange except it runs over CCNx Layer 3 messages 🌈. trust is out of scope for Layer 3 and gets left to applications or application frameworks πŸ‘‘

combining an ephemeral key exchange (like CCNxKE [ccnxke]) with an encapsulating encryption (like [esic]) gives you the equivalent of a TLS tunnel πŸ”’βœ¨. intermediate nodes can forward Interests and Content Objects but they have zero visibility inside πŸ‘€. it also completely hides the internal names from the encryption layer πŸ™ˆ. this kind of tunneling encryption is useful for content with little or no cacheability, since only someone with the ephemeral key can use it πŸ’œ. short-term caching can help with lossy links or mobility, but long-term caching is usually not of interest 🌸

broadcast encryption or proxy re-encryption might be useful for content with multiple uses over time or lots of consumers πŸŽ€. there is currently no recommendation for this form of encryption πŸ€·β€β™€οΈ

the specific encoding of messages has security implications 🧐. this document uses a Type-Length-Value (TLV) encoding, and we chose to compromise between extensibility and unambiguous encodings of types and lengths πŸ“. some TLV encodings use variable-length T and variable-length L fields to fit a wide gamut of values while staying byte efficient, but our TLV encoding uses a fixed length 2-byte T and 2-byte L πŸ’…. fixed-length T and L fields solve two problems πŸ”₯

the first problem is aliases. if you can encode the same value, like 0x02 and 0x0002, in different byte lengths, then you have to decide if they mean the same thing, if they're different, or if one of them is illegal 😡. if they're different, you must always compare the buffers, not the integer equivalents 🧩. if one is illegal, you must validate the TLV encoding, every field of every packet at every hop 😩. if they're the same, you hit the second problem: how to specify packet filters πŸ’€. for example, if a name has 6 name components, there are 7 T fields and 7 L fields, and each might have up to 4 representations of the same value 🀯. that's 14 fields with 4 encodings each, or 1001 combinations. it also means you can't compare a name with a memory function, because you have to consider that any embedded T or L might have a different format 😭

the Interest Return message has no authenticator from the previous hop πŸ™ƒ. so the payload of the Interest Return should ONLY be used locally to match an Interest 🫢. a node should never forward that Interest payload as an Interest 🚫. it should also verify that it sent the Interest in the Interest Return to that node, and not let anyone negate Interest messages πŸ›‘οΈ

caching nodes have to be careful when processing content objects 🧁. it is essential that the Content Store follows the rules outlined in [RFC8569] to avoid certain types of attacks πŸ“œ. CCNx 1.0 has no mechanism to work around an undesired result from the network (there are no "excludes"), so if a cache gets poisoned with bad content, it might cause problems retrieving content later 😱. there are three types of access to content from a Content Store: unrestricted, signature restricted, and hash restricted 🌈. if an Interest has no restrictions, the requester isn't picky about what they get back, so any matching cached object is OK πŸƒ. in the hash restricted case, the requester is super specific about what they want, and the Content Store (and every forward hop) can easily verify that the content matches the request 🎯. in the signature restricted case (which is often used for initial manifest discovery), the requester only knows the KeyId that signed the content πŸ”‘. this case needs the closest attention in the Content Store so it doesn't amplify bad data 🚨. the Content Store must ONLY respond with a content object if it can verify the signature, meaning either the content object carries the public key inside it, or the Interest carries the public key in addition to the KeyId πŸ™Œ. if that's not the case, the Content Store should treat the Interest as a cache miss and let an endpoint respond πŸ’β€β™€οΈ

a user-level cache could do full signature verification by fetching a public key according to the PublicKeyLocator 🧠. however, that's not a burden we want to put on the forwarder πŸ™…β€β™€οΈ. a user-level cache could also rely on out-of-band attestation, like the cache operator only inserting content they know has the correct signature πŸŽ€

the CCNx grammar allows hash algorithm agility via the HashType πŸ”„. it specifies a short list of acceptable hash algorithms that should be implemented at each forwarder πŸ“‹. some hash values only apply to end systems, so updating the hash algorithm does not affect forwarders, since they would simply match the buffer that includes the type-length-hash buffer πŸ¦‹. some fields, like the ConObjHash, must be verified at each hop, so a forwarder (or related system) must know the hash algorithm, and it could cause backward compatibility problems if the hash type gets updated 😬

a CCNx name uses binary matching, whereas a URI uses a case-insensitive hostname πŸ”€. some systems may also use case-insensitive matching of the URI path to a resource 🌸. this means human-entered CCNx names will likely have case or non-ASCII symbol mismatches unless you use a consistent URI normalization for the CCNx name πŸ™ˆ. it also means an entity that registers a CCNx-routable prefix, say "ccnx:/example.com", would need separate registrations for simple variations like "ccnx:/Example.com" 🧐. unless this is addressed in URI normalization and routing protocol conventions, there could be phishing attacks 🎣⚠️

for a more general intro to ICN-related security concerns and approaches, check out [RFC7927] and [RFC7945] πŸ“–πŸ«Ά


6. References ✨

6.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>.

[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>.

6.2. Informative References πŸ“šβœ¨

okay bestie, these are the extra reading refs πŸ€“ not required to implement the thing, but they're the good stuff for the backstory. the ICN research, the key exchange drafts, the compression slides, all of it πŸ’œ

[ace] Shang, W., Yu, Y., Liang, T., Zhang, B., and L. Zhang, "NDN-ACE: Access control for constrained environments over named data networking", NDN Technical Report NDN-0036, 2015, http://new.named-data.net/wp-content/uploads/2015/12/ndn-0036-1-ndn-ace.pdf.

[ccnxke] Mosko, M., Uzun, E., and C. Wood, "CCNx Key Exchange Protocol Version 1.0", Work in Progress, draft-wood-icnrg-ccnxkeyexchange-02, March 2017.

[CCNxURI] Mosko, M. and C. Wood, "The CCNx URI Scheme", Work in Progress, draft-mosko-icnrg-ccnxurischeme-01, April 2016.

[CCNxz] Mosko, M., "CCNxz TLV Header Compression Experimental Code", commit f1093a2, March 2018, https://github.com/PARC/CCNxz.

[compress] Mosko, M., "Header Compression for TLV-based Packets", ICNRG Interim Meeting, 2016, https://datatracker.ietf.org/meeting/interim-2016-icnrg-02/materials/slides-interim-2016-icnrg-2-7.

[ECC] Certicom Research, "SEC 2: Recommended Elliptic Curve Domain Parameters", 2010, http://www.secg.org/sec2-v2.pdf.

[esic] Mosko, M. and C. Wood, "Encrypted Sessions In CCNx (ESIC)", Work in Progress, draft-wood-icnrg-esic-01, September 2017.

[IANA-PEN] IANA, "Private Enterprise Numbers", http://www.iana.org/assignments/enterprise-numbers.

[mobile] Mosko, M., Uzun, E., and C. Wood, "Mobile Sessions in Content-Centric Networks", IFIP Networking, 2017, http://dl.ifip.org/db/conf/networking/networking2017/1570334964.pdf.

[nnc] Jacobson, V., Smetters, D., Thornton, J., Plass, M., Briggs, N., and R. Braynard, "Networking Named Content", Proceedings of the 5th international conference on Emerging networking experiments and technologies (CoNEXT '09), 2009, http://dx.doi.org/10.1145/1658939.1658941.

[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008, https://www.rfc-editor.org/info/rfc5280.

[RFC7927] Kutscher, D., Ed., Eum, S., Pentikousis, K., Psaras, I., Corujo, D., Saucez, D., Schmidt, T., and M. Waehlisch, "Information-Centric Networking (ICN) Research Challenges", RFC 7927, DOI 10.17487/RFC7927, July 2016, https://www.rfc-editor.org/info/rfc7927.

[RFC7945] Pentikousis, K., Ed., Ohlman, B., Davies, E., Spirou, S., and G. Boggia, "Information-Centric Networking: Evaluation and Security Considerations", RFC 7945, DOI 10.17487/RFC7945, September 2016, https://www.rfc-editor.org/info/rfc7945.

[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, https://www.rfc-editor.org/info/rfc8126.

[RFC8569] Mosko, M., Solis, I., and C. Wood, "Content-Centric Networking (CCNx) Semantics", RFC 8569, DOI 10.17487/RFC8569, July 2019, https://www.rfc-editor.org/info/rfc8569.


Authors' Addresses 🫢

the authors, with their contact details, exactly as they wrote them πŸ’…

Marc Mosko
PARC, Inc.
Palo Alto, California  94304
United States of America

Phone: +01 650-812-4405
Email: mmosko@parc.com


Ignacio Solis
LinkedIn
Mountain View, California  94043
United States of America

Email: nsolis@linkedin.com


Christopher A. Wood
University of California, Irvine
Irvine, California  92697
United States of America

Phone: +01 315-806-5939
Email: woodc1@uci.edu

and that's a wrap on RFC 8609!! πŸŒˆπŸ‘‘ literally so proud of us πŸ˜­πŸŽ€

πŸ“¦ where this page comes from