RFC 9174
Delay-Tolerant Networking TCP Convergence-Layer Protocol Version 4
Part 1 of 17
RFC 9174: Delay-Tolerant Networking TCP Convergence-Layer Protocol Version 4 π¦
okay bestie, let's start with the title block because it's giving official paperwork πβ¨. This is RFC 9174, and it's a Standards Track document, which means it's the real deal and not just an experiment. It was published in January 2022 by the IETF, and the ISSN is 2070-1721 π.
The authors are B. Sipos (listed with RKF Engineering), M. Demmer, J. Ott (Technical University of Munich), and S. Perreault (LogMeIn). π«Ά
The header doesn't list any RFC this one obsoletes or updates. It does mention that it's the follow-up to TCPCL version 3, which is defined in RFC 7242, so it's basically the glow-up of that earlier version πΈ.
Abstract π
okay so this document describes a TCP convergence layer (TCPCL) for Delay-Tolerant Networking (DTN). TCPCLv4 fixes the implementation problems that showed up in TCPCL version 3 (the one from RFC 7242) π§, and it also updates the contents, encodings, and convergence-layer requirements for the Bundle Protocol version 7 (BPv7) π .
The big idea is that TCPCLv4 uses BPv7 bundles encoded with Concise Binary Object Representation (CBOR) as the service data unit it carries, and it gives those bundles a reliable transport π. The version also comes with security and extensibility mechanisms, so it's not lacking anything π.
Status of This Memo π
this is an Internet Standards Track document, so it's officially part of the Internet Standards world π.
It's a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) β . If you want to know more about Internet Standards, check out Section 2 of RFC 7841 π.
For the current status, any errata, and how to send feedback, go to https://www.rfc-editor.org/info/rfc9174 π.
Copyright Notice π§Ύ
Copyright (c) 2022 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) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License π.
Table of Contents π
1. Introduction
1.1. Scope
2. Requirements Language
2.1. Definitions Specific to the TCPCL Protocol
3. General Protocol Description
3.1. Convergence-Layer Services
3.2. TCPCL Session Overview
3.3. TCPCL States and Transitions
3.4. PKIX Environments and CA Policy
3.5. Session-Keeping Policies
3.6. Transfer Segmentation Policies
3.7. Example Message Exchange
4. Session Establishment
4.1. TCP Connection
4.2. Contact Header
4.3. Contact Validation and Negotiation
4.4. Session Security
4.4.1. Entity Identification
4.4.2. Certificate Profile for the TCPCL
4.4.3. TLS Handshake
4.4.4. TLS Authentication
4.4.5. Policy Recommendations
4.4.6. Example TLS Initiation
4.5. Message Header
4.6. Session Initialization Message (SESS_INIT)
4.7. Session Parameter Negotiation
4.8. Session Extension Items
5. Established Session Operation
5.1. Upkeep and Status Messages
5.1.1. Session Upkeep (KEEPALIVE)
5.1.2. Message Rejection (MSG_REJECT)
5.2. Bundle Transfer
5.2.1. Bundle Transfer ID
5.2.2. Data Transmission (XFER_SEGMENT)
5.2.3. Data Acknowledgments (XFER_ACK)
5.2.4. Transfer Refusal (XFER_REFUSE)
5.2.5. Transfer Extension Items
6. Session Termination
6.1. Session Termination Message (SESS_TERM)
6.2. Idle Session Termination
7. Security Considerations
7.1. Threat: Passive Leak of Node Data
7.2. Threat: Passive Leak of Bundle Data
7.3. Threat: TCPCL Version Downgrade
7.4. Threat: Transport Security Stripping
7.5. Threat: Weak TLS Configurations
7.6. Threat: Untrusted End-Entity Certificate
7.7. Threat: Certificate Validation Vulnerabilities
7.8. Threat: Symmetric Key Limits
7.9. Threat: BP Node Impersonation
7.10. Threat: Denial of Service
7.11. Mandatory-to-Implement TLS
7.12. Alternate Uses of TLS
7.12.1. TLS without Authentication
7.12.2. Non-certificate TLS Use
7.13. Predictability of Transfer IDs
8. IANA Considerations
8.1. Port Number
8.2. Protocol Versions
8.3. Session Extension Types
8.4. Transfer Extension Types
8.5. Message Types
8.6. XFER_REFUSE Reason Codes
8.7. SESS_TERM Reason Codes
8.8. MSG_REJECT Reason Codes
8.9. Object Identifier for PKIX Module Identifier
8.10. Object Identifier for PKIX Other Name Forms
8.11. Object Identifier for PKIX Extended Key Usage
9. References
9.1. Normative References
9.2. Informative References
Appendix A. Significant Changes from RFC 7242
Appendix B. ASN.1 Module
Appendix C. Example of the BundleEID Other Name Form
Acknowledgments
Authors' Addresses
1. Introduction πΈ
okay so this document describes the TCP convergence-layer protocol for Delay-Tolerant Networking (DTN). DTN is an end-to-end architecture for communicating in and/or through seriously rough environments: intermittent connectivity, long and/or variable delays, and high bit error rates π. If you want the full story on why these networks exist and what they can do, check out "Delay-Tolerant Networking Architecture" [RFC4838] π.
The DTN architecture is all about supporting a wide range of networking technologies and environments π. The protocol DTN uses is the Bundle Protocol version 7 (BPv7) [RFC9171]. It's an application-layer protocol that builds a store-and-forward overlay network π§. BPv7 needs a "convergence-layer adapter" (CLA) to send and receive bundles over some "native" link, network, or Internet protocol π. This document describes one of those adapters, the one that rides on the well-known Transmission Control Protocol (TCP). That convergence layer is called TCP Convergence Layer version 4 (TCPCLv4) π.
For the rest of this document:
- the abbreviation "BP" without the version suffix refers to BPv7.
- the abbreviation "TCPCL" without the version suffix refers to TCPCLv4.
Now, where do the TCPCL and the Bundle Protocol sit in the Internet model protocol stack? That's described in [RFC1122], and it's shown in Figure 1 π₯°. When BP uses TCP as its bearer with the TCPCL as its convergence layer, both BP and the TCPCL live at the application layer of the Internet model, which is a very main character move π.
+-------------------------+
| DTN Application | -\
+-------------------------| |
| Bundle Protocol (BP) | -> Application Layer
+-------------------------+ |
| TCP Conv. Layer (TCPCL) | |
+-------------------------+ |
| TLS (optional) | -/
+-------------------------+
| TCP | ---> Transport Layer
+-------------------------+
| IPv4/IPv6 | ---> Network Layer
+-------------------------+
| Link-Layer Protocol | ---> Link Layer
+-------------------------+
Figure 1: The Locations of the Bundle Protocol and the TCP
Convergence-Layer Protocol above the Internet Protocol Stack
1.1. Scope π―
this section is about what's actually in scope. This document describes the format of the protocol data units that get passed between entities taking part in TCPCL communications. It does not cover:
- The format of protocol data units of the Bundle Protocol, since those are defined elsewhere in [RFC9171]. That includes bundle fragmentation and bundle encapsulation. The TCPCL just transfers bundles as opaque data blocks π¦.
- Ways of locating or identifying other bundle entities (peers) inside a network or across an internet. Mapping a node ID to a potential convergence layer (CL) protocol and network address is left to the implementation and configuration of the BP Agent (BPA) and its various routing strategies. The same goes for mapping a DNS name and/or address to an end-entity certificate used to authenticate a node to its peers πΊοΈ.
- Logic for routing bundles along a path toward a bundle's endpoint. This CL protocol is only involved in moving bundles between adjacent entities in a routing sequence π€οΈ.
- Policies or mechanisms for issuing Public Key Infrastructure Using X.509 (PKIX) certificates. That also covers provisioning, deploying, or accessing certificates and private keys, deploying or accessing certificate revocation lists (CRLs), and configuring security parameters on an individual entity or across a network π.
- Uses of TLS that are not based on PKIX certificate authentication (see Section 7.12.2), or in which authentication of both entities is not possible (see Section 7.12.1) π ββοΈ.
Any TCPCL implementation needs a BPA to handle those functions above, so that end-to-end bundle delivery can actually happen π .
2. Requirements Language π
the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here π. So if you see them in ALL CAPS, that's the official spec energy, and if you don't, they're just regular words π«Ά.
2.1. Definitions Specific to the TCPCL Protocol π
okay so this bit is where we pin down the exact vocab for TCPCL, bestie π every term here gets used the same way for the rest of the doc, so let's make sure we're on the same page.
Network Byte Order: here, "network byte order" means most significant byte first, a.k.a. big endian. πΈ All of the integer encodings in this protocol SHALL be transmitted in network byte order. no exceptions, it's giving strict π
TCPCL Entity: this is the notional TCPCL application that initiates TCPCL sessions. π§ How an entity is designed, implemented, configured, and specifically behaves is outside the scope of this document. BUT the concept of an entity is still super useful here, because it's the container and initiator of TCPCL sessions. The relationship between a TCPCL entity and TCPCL sessions goes like this:
- A TCPCL entity MAY actively initiate any number of TCPCL sessions, and should do so whenever the entity is the initial transmitter of information to another entity in the network. π¦
- A TCPCL entity MAY support zero or more passive listening elements that listen for connection requests from other TCPCL entities operating on other entities in the network. π
- A TCPCL entity MAY passively initiate any number of TCPCL sessions from requests received by its passive listening element(s), if the entity uses such elements. β¨
These relationships are shown in Figure 2. For most TCPCL behavior within a session, the two entities are symmetric, so there's no protocol distinction between them. π«Ά Some specific behavior, especially during session establishment, does split them into the active entity and the passive entity. For the rest of this document, the term "entity" without the prefix "TCPCL" refers to a TCPCL entity.
TCP Connection: the term "connection" in this specification exclusively refers to a TCP connection, plus any and all behaviors, sessions, and other states associated with that TCP connection. π§
TCPCL Session: a TCPCL session (as opposed to a TCP connection) is a TCPCL communication relationship between two TCPCL entities. π A TCPCL session runs inside a single underlying TCP connection, and its lifetime is bound to the lifetime of that connection. A TCPCL session is terminated when the TCP connection ends, which happens either because (1) one or both entities actively close the TCP connection, or (2) network errors cause the TCP connection to fail. Within one TCPCL session there are two possible transfer streams, one in each direction. One stream from each entity is the outbound stream, and the other is the inbound stream (see Figure 3). π From the perspective of a TCPCL session, the two transfer streams don't logically interact with each other. They do run over the same TCP connection and between the same BPAs, though, so there are logical relationships at those layers (message and bundle interleaving, respectively). For the rest of this document, the term "session" without the prefix "TCPCL" refers to a TCPCL session.
Session Parameters: these are a set of values used to affect how the TCPCL operates for a given session. β How these parameters get conveyed to the bundle entity, and therefore to the TCPCL, is implementation dependent. The mechanism by which two entities exchange and negotiate the values to be used for a given session is described in Section 4.3.
Transfer Stream: a transfer stream is a unidirectional user-data path within a TCPCL session. π Transfers sent over a transfer stream are serialized, meaning one transfer must finish transmitting before another transfer can start over that same stream. At the stream layer there's no logical relationship between transfers in that stream. It's only within the BPA that transfers get fully decoded as bundles. Each unidirectional stream has a single sender entity and a single receiver entity. π
Transfer: this refers to the procedures and mechanisms for conveying an individual bundle from one node to another. π¦ Each transfer within the TCPCL is identified by a Transfer ID number, which is guaranteed to be unique only to a single direction within a single session.
Transfer Segment: a transfer segment is a subset of a transfer of user data being communicated over a transfer stream. π§©
Idle Session: a TCPCL session is idle while there's no transmission in progress in either direction. π΄ While idle, the only messages being transmitted or received are KEEPALIVE messages.
Live Session: a TCPCL session is live while there's a transmission in progress in either direction. β‘
Reason Codes: the TCPCL uses numeric codes to encode specific reasons for individual failure/error message types. π’
The relationship between connections, sessions, and streams is shown in Figure 3.
+--------------------------------------------+
| TCPCL Entity |
| | +----------------+
| +--------------------------------+ | | |-+
| | Actively Initiated Session #1 +------------->| Other | |
| +--------------------------------+ | | TCPCL Entity's | |
| ... | | Passive | |
| +--------------------------------+ | | Listener | |
| | Actively Initiated Session #n +------------->| | |
| +--------------------------------+ | +----------------+ |
| | +-----------------+
| +---------------------------+ |
| +---| +---------------------------+ | +----------------+
| | | | Optional Passive | | | |-+
| | +-| Listener(s) +<-------------+ | |
| | +---------------------------+ | | | |
| | | | Other | |
| | +---------------------------------+ | | TCPCL Entity's | |
| +--->| Passively Initiated Session #1 +-------->| Active | |
| | +---------------------------------+ | | Initiator(s) | |
| | | | | |
| | +---------------------------------+ | | | |
| +--->| Passively Initiated Session #n +-------->| | |
| +---------------------------------+ | +----------------+ |
| | +-----------------+
+--------------------------------------------+
Figure 2: The Relationships between TCPCL Entities
+---------------------------+ +---------------------------+
| "Own" TCPCL Session | | "Other" TCPCL Session |
| | | |
| +----------------------+ | | +----------------------+ |
| | TCP Connection | | | | TCP Connection | |
| | | | | | | |
| | +-----------------+ | | Messages | | +-----------------+ | |
| | | Own Inbound | +--------------------+ | Peer Outbound | | |
| | | Transfer Stream | | Transfer Stream | | |
| | | ----- |<---[Seg]--[Seg]--[Seg]---| ----- | | |
| | | RECEIVER |---[Ack]----[Ack]-------->| SENDER | | |
| | +-----------------+ +-----------------+ | |
| | | |
| | +-----------------+ +-----------------+ | |
| | | Own Outbound |-------[Seg]---[Seg]----->| Peer Inbound | | |
| | | Transfer Stream |<---[Ack]----[Ack]-[Ack]--| Transfer Stream | | |
| | | ----- | | ----- | | |
| | | SENDER | +--------------------+ | RECEIVER | | |
| | +-----------------+ | | | | +-----------------+ | |
| +-----------------------+ | | +---------------------+ |
+----------------------------+ +--------------------------+
Figure 3: The Relationship within a TCPCL Session of its Two Streams
3. General Protocol Description πΈ
okay now we get to the main event β¨ the service this protocol provides is transmitting DTN bundles over TCP. π¦ This document specifies how bundles get encapsulated, the procedures for TCP setup and teardown, and a set of messages and entity requirements. Here's the general vibe of how the protocol works:
3.1. Convergence-Layer Services β¨
okay bestie, this part is all about the services the TCPCL gives to the overlaying BPA π . Quick heads-up: this is NOT an API definition. It's just a logical description of how the CL and the BPA can talk to each other π¬. Each interaction can also come with any number of extra metadata items, as needed to keep the CL or BPA running smoothly π.
- Attempt Session: The TCPCL lets a BPA preemptively try to set up a TCPCL session with a peer entity π¦. Each attempt can send a different set of session negotiation parameters, as the BPA directs.
- Terminate Session: The TCPCL also lets a BPA preemptively end an established TCPCL session with a peer entity πΈ. The terminate request happens on a per-session basis.
- Session State Changed: The TCPCL entity tells the BPA whenever the session state changes π. The top-level session states it reports are:
Connecting: A TCP connection is being established. This state only applies to the active entity.Contact Negotiating: A TCP connection has been made (as either the active or passive entity), and contact negotiation has begun.Session Negotiating: Contact negotiation is done (including possible TLS use), and session negotiation has begun.Established: The session is fully set up and ready for its first transfer β¨. Once it's established, the peer node ID (plus whether or not it was authenticated) and the negotiated session parameters (see Section 4.7) are also passed along to the BPA.Ending: The entity sent a SESS_TERM message and is now in the Ending state π«Ά.Terminated: The session finished normal termination sequencing π§.Failed: The session ended WITHOUT normal termination sequencing π.
- Session Idle Changed: The TCPCL entity tells the BPA when the Live/Idle substate of the session changes π. This only happens when the top-level session state is "Established". The session goes from Idle to Live at the start of a transfer in either transfer stream, and goes from Live back to Idle at the end of a transfer when the other transfer stream has no ongoing transfer. And here's the tea: because the TCPCL sends things serially over a TCP connection, it suffers from "head-of-queue blocking" π. That means a transfer in either direction can block an immediate start of a new transfer in the session.
- Begin Transmission: The main purpose of the TCPCL is to let a BPA transmit bundle data over an established TCPCL session π₯. Transmission requests happen on a per-session basis, and the CL does not necessarily do any per-session or inter-session queueing. Any queueing of transmissions is the BPA's job π .
- Transmission Success: The TCPCL entity tells the BPA when a bundle has been fully transferred to a peer entity π.
- Transmission Intermediate Progress: The TCPCL entity tells the BPA how far along a transfer to a peer entity is π. This progress is reported at the granularity of each transferred segment.
- Transmission Failure: The TCPCL entity tells the BPA about certain reasons a bundle transmission failed π. The big ones are when the peer entity rejects the bundle, or when a TCPCL session ends before the transfer succeeds. The TCPCL itself does not have a notion of transfer timeout β³.
- Reception Initialized: The TCPCL entity tells the receiving BPA this just before any transmission data is sent π. This corresponds to receiving the XFER_SEGMENT message with the
STARTflag set to 1. - Interrupt Reception: The TCPCL entity lets a BPA interrupt an individual transfer before it has fully completed, whether successfully or not π. Interruption can happen any time after reception is initialized.
- Reception Success: The TCPCL entity tells the BPA when a bundle has been fully transferred from a peer entity π₯³.
- Reception Intermediate Progress: The TCPCL entity tells the BPA how far along a transfer from the peer entity is π§. This progress is reported at the granularity of each transferred segment. Intermediate reception gives a BPA the chance to inspect bundle header contents before the entire bundle is available, which is what makes the "Interrupt Reception" capability work π¦.
- Reception Failure: The TCPCL entity tells the BPA about certain reasons reception failed π«. The big ones are when the local entity rejects an attempted transfer for some local policy reason, or when a TCPCL session ends before the transfer succeeds. Again, the TCPCL itself does not have a notion of transfer timeout β³.
3.2. TCPCL Session Overview πΈ
okay so first, one entity sets up a TCPCL session to the other by opening a TCP connection in accordance with [RFC0793] π§. Once the TCP connection setup is done, an initial Contact Header gets exchanged in both directions. This is how they agree on a shared TCPCL version and negotiate the use of TLS security (as described in Section 4) π. Once contact negotiation is complete, TCPCL messaging is available, and session negotiation is used to set the parameters of the TCPCL session π. One of these parameters is a node ID. Each TCPCL entity is acting on behalf of a BPA that has a node ID. The node ID helps with routing and forwarding messages by the BPA, and it's part of the authentication capability TLS provides π«Ά.
Once negotiated, the parameters of a TCPCL session CANNOT change π ββοΈ. If either peer wants to transfer data under different parameters, a new session has to be established. This keeps the CL logic simpler, but it relies on the assumption that establishing a TCP connection is lightweight enough that the TCP connection overhead is negligible compared to TCPCL data sizes π .
Once the TCPCL session is established and configured this way, bundles can be transferred in either direction β¨. Each transfer is done by segmenting the transfer data into one or more XFER_SEGMENT messages. Multiple bundles can be sent back to back in a single direction on a single TCPCL connection. Segments from different bundles are NEVER interleaved π. Bundle interleaving can be achieved either by fragmentation at the BP layer or by setting up multiple TCPCL sessions between the same peers π. There's no fundamental limit on how many TCPCL sessions a single entity can establish, except for the limit set by the number of available (ephemeral) TCP ports of the active entity π.
One feature of this protocol is that the receiving entity can send acknowledgment (XFER_ACK) messages as bundle data segments arrive π¦. The whole point of these acknowledgments is to let the transmitting entity figure out how much of the bundle has been received. That way, if the session gets interrupted, it can do reactive fragmentation and avoid resending the part that's already been transmitted π. On top of that, the TCPCL has no explicit flow control π€·ββοΈ.
A TCPCL receiver can interrupt the transmission of a bundle at any point by replying with a XFER_REFUSE message π. This makes the sender stop transmitting the associated bundle, if it hasn't already finished.
Note: This enables a cross-layer optimization. It lets a receiver that detects it already has a certain bundle interrupt the transmission as early as possible, which saves transmission capacity for other bundles π§ .
For sessions that are idle, a KEEPALIVE message is sent at a negotiated interval π. This is how entities convey liveness information during stretches of time with no other messages π.
A SESS_TERM message is used to start ending a TCPCL session (see Section 6.1) π₯Ί. During termination sequencing, transfers already in progress can be completed, but no new transfers can be started π¦. A SESS_TERM message can also be used to refuse a session setup from a peer (see Section 4.3) π . Whatever the reason, session termination is started by one of the entities, and the other entity responds to it, as shown in Figures 13 and 14 in the next subsection π¬. Even when no transfers are queued or in progress, the session termination procedure lets each entity tell apart a clean end to a session from the TCP connection closing because of some underlying network issue π§.
Once a session is established, the TCPCL is a symmetric protocol between the peers π«. Both sides can start sending data segments in a session, and one side's bundle transfer doesn't have to finish before the other side can start sending data segments of its own. So the protocol supports bidirectional communication π. Note that when transmission is happening in both directions at once, acknowledgment segments MAY be interleaved with data segments πΈ.
3.3. TCPCL States and Transitions β¨
okay so this is the part where we map out the whole life of a TCPCL session, bestie π¦ The states of a normal session (the no-drama version, no session failures) are shown in Figure 4 π
+-------+
| START |
+-------+
|
TCP Establishment
|
V
+-----------+ +---------------------+
| TCP |----------->| Contact / Session |
| Connected | | Negotiation |
+-----------+ +---------------------+
|
+-----Session Parameters-----+
| Negotiated
V
+-------------+ +-------------+
| Established |----New Transfer---->| Established |
| Session | | Session |
| Idle |<---Transfers Done---| Live |
+-------------+ +-------------+
| |
+------------------------------------+
|
V
+-------------+
| Established | +-------------+
| Session |----Transfers------>| TCP |
| Ending | Done | Terminating |
+-------------+ +-------------+
|
+----------TCP Close Message----------+
|
V
+-------+
| END |
+-------+
Figure 4: Top-Level States of a TCPCL Session
Quick notes on the established session states, because these three are everything π«Ά
- Session "Live" means transmitting or receiving over a transfer stream. π₯
- Session "Idle" means no transmission/reception over a transfer stream. π΄
- Session "Ending" means no new transfers will be allowed. π«
Now, contact negotiation! πΈ Both sides swap a Contact Header ("CH" in Figures 5, 6, and 7) in both directions, and then they each derive a negotiated state from the two headers. Literally the vibe is "you show me yours, I show you mine" π The sequencing is done as either the active or passive entity and is drawn in Figures 5 and 6, respectively. Both of those share the data validation and negotiation of the Processing of Contact Header ("[PCH]") activity (Figure 7), plus the "[TCPCLOSE]" activity, which just means the TCP connection gets closed π If negotiation works out, one of the Session Initiation ("[SI]") activities happens, as you'll see further below β¨ And to avoid data loss, a Session Termination ("[ST]") exchange lets everyone cleanly finish their transfers before the session ends. No one gets ghosted mid-transfer, periodt π
+-------+
| START |
+-------+
|
TCP Connecting
V
+-----------+
| TCP | +---------+
| Connected |--Send CH-->| Waiting |--Timeout-->[TCPCLOSE]
+-----------+ +---------+
|
Received CH
V
[PCH]
Figure 5: Contact Initiation as Active Entity
+-----------+ +---------+
| TCP |--Wait for-->| Waiting |--Timeout-->[TCPCLOSE]
| Connected | CH +---------+
+-----------+ |
Received CH
V
+-----------------+
| Preparing reply |--Send CH-->[PCH]
+-----------------+
Figure 6: Contact Initiation as Passive Entity
+-----------+
| Peer CH |
| available |
+-----------+
|
Validate and
Negotiate
V
+------------+
| Negotiated |--Failure-->[TCPCLOSE]
+------------+
| |
No TLS +----Negotiate---+ [ST]
| TLS | ^
V | Failure
+-----------+ V |
| TCPCL | +---------------+
| Messaging |<--Success--| TLS Handshake |
| Available | +---------------+
+-----------+
Figure 7: Processing of Contact Header [PCH]
Session negotiation is next, and it's giving the same energy π¦ Both entities swap a session initialization (SESS_INIT) message in both directions and derive a negotiated state from the two messages. It's done as either the active or passive entity, shown in Figures 8 and 9, respectively (where "[PSI]" means "Processing of Session Initiation"). Both of those share the data validation and negotiation shown in Figure 10. And the validation here includes certificate validation and authentication when TLS is used for the session, so yes, security is in the mix π
+-----------+
| TCPCL | +---------+
| Messaging |--Send SESS_INIT-->| Waiting |--Timeout-->[ST]
| Available | +---------+
+-----------+ |
Received SESS_INIT
|
V
[PSI]
Figure 8: Session Initiation [SI] as Active Entity
+-----------+
| TCPCL | +---------+
| Messaging |----Wait for ---->| Waiting |--Timeout-->[ST]
| Available | SESS_INIT +---------+
+-----------+ |
Received SESS_INIT
|
+-----------------+
| Preparing reply |--Send SESS_INIT-->[PSI]
+-----------------+
Figure 9: Session Initiation [SI] as Passive Entity
+----------------+
| Peer SESS_INIT |
| available |
+----------------+
|
Validate and
Negotiate
V
+------------+
| Negotiated |---Failure--->[ST]
+------------+
|
Success
V
+--------------+
| Established |
| Session Idle |
+--------------+
Figure 10: Processing of Session Initiation [PSI]
Transfers can happen once a session is established, as long as it's not in the Ending state π Each transfer happens inside a single logical transfer stream between a sender and a receiver, as drawn in Figures 11 and 12, respectively β¨
+--Send XFER_SEGMENT--+
+--------+ | |
| Stream | +-------------+ |
| Idle |---Send XFER_SEGMENT-->| In Progress |<------------+
+--------+ +-------------+
|
+---------All segments sent-------+
|
V
+---------+ +--------+
| Waiting |---- Receive Final---->| Stream |
| for Ack | XFER_ACK | Idle |
+---------+ +--------+
Figure 11: Transfer Sender States
| Note on transfer sending: Pipelining of transfers can occur
| when the sending entity begins a new transfer while in the
| "Waiting for Ack" state.
+-Receive XFER_SEGMENT-+
+--------+ | Send XFER_ACK |
| Stream | +-------------+ |
| Idle |--Receive XFER_SEGMENT-->| In Progress |<-------------+
+--------+ +-------------+
|
+--------Sent Final XFER_ACK--------+
|
V
+--------+
| Stream |
| Idle |
+--------+
Figure 12: Transfer Receiver States
Session termination is a two-person dance π One entity starts terminating the session and the other one acknowledges it. For either entity, it's sending the SESS_TERM message that moves the session into the Ending substate. And once a session is in the Ending state, only in-progress transfers can be finished, and no new transfers can be started π«π
+-----------+ +---------+
| Session |--Send SESS_TERM-->| Session |
| Live/Idle | | Ending |
+-----------+ +---------+
Figure 13: Session Termination [ST] from the Initiator
+-----------+ +---------+
| Session |--Send SESS_TERM-->| Session |
| Live/Idle | | Ending |
+-----------+<------+ +---------+
| |
Receive SESS_TERM |
| |
+-------------+
Figure 14: Session Termination [ST] from the Responder
3.4. PKIX Environments and CA Policy β¨
okay bestie, let's talk about certificates π this section is all about how a TCPCL entity uses PKIX certificates. the spec does NOT tell you how those certs get made or handed out, only how to use them once you have them π
the vibe is that there are two super different PKIX worlds, and the TCPCL has to work in both π
DTN-Aware CAs: this is the dream π the CA knows the cert is for DTN use, has a way to check you actually own a node ID, and issues the cert straight to that node ID. so you can authenticate the node ID itself, no detours through a network name or address and then hoping the node ID is legit. the TCPCL authenticates the node ID whenever it can, and that is preferred over the lower-level PKIX identities. main character energy π
DTN-Ignorant CAs: this is the real-world internet π public CAs are gonna keep focusing on DNS names, because the infrastructure for that is already huge (see [RFC8555] for the identity verification side). the TCPCL works here too, by authenticating a lower-level identifier for the peer and then trusting that the node ID the peer gives you during session initialization is valid. not ideal, ngl π it opens up the vulnerabilities described in Section 7.9, BUT you still get some amount of mutual authentication, so it's not a total loss π¦
even inside one single session, each entity can be in a different PKI environment with different identifier limits π§ the identifier requirements for PKIX certs are in Section 4.4.1, so go check those out π
now the security policy part, which is so important for interop π₯ every TCPCL entity should have its own security policy tailored to the peers it's gonna talk to. Section 4.4.5 has some recommendations, but they're just a starting point, so you gotta tailor them π
a strict TLS policy makes sense for a private network with one shared CA π but if you're on the open internet (like inter-site BP gateways), you could go with looser TCPCL security and lean on encrypted bundle encapsulation [DTN-BIBECT] to get strong bundle security instead πΈ
and here's a fun trick β¨ with the Server Name Indication (SNI) DNS name (see Section 4.4.3), one passive entity can act as a convergence layer for multiple BPAs with different node IDs. that's the "virtual host" behavior π the DNS name tells you which BP node the active entity is trying to reach π
a virtual host CL entity can prove who it is in two ways: one certificate that covers all the DNS names and/or node IDs it hosts, OR several certificates, each covering a single DNS name and/or node ID, and it uses the SNI value from the peer to pick the right one π«Ά how the SNI-to-cert mapping works is up to the implementation, and it can involve matching a DNS name to a node ID or to other cert attributes π
3.5. Session-Keeping Policies π¦
okay so this section is about when and how a TCPCL session gets started, kept alive, and ended π the spec does not force any session management rules on the BPA. that's a network admin decision π but the guidance here can help steer your policy toward whatever performance goals you have π
Persistent Session: this one is like keeping a friend on speed dial π you set up one session to known entities ahead of time and keep it alive with KEEPALIVEs. the upsides: you send way less TCP data for a bunch of transfers (assuming KEEPALIVEs are much smaller than the transfers), and the session state can tell you if a peer is connected β¨ the downsides: wasted resources when the session is mostly idle or the connection is flaky (so failed sessions have to be re-established π), and possible queueing problems when a bunch of transfers get requested at once π this policy also assumes both peers agree on who starts the sessions. if they don't agree, you can end up with duplicate sessions between the same peers π
Ephemeral Sessions: this is the "only when needed" approach πΈ a session only gets set up when an outgoing transfer needs to go out. upsides: no wasting resources on sessions sitting idle for ages, and you dodge the queueing issues you can get with one persistent session π«Ά downsides: every transfer pays the TCP and TLS overhead of setting up a new session π₯² this policy assumes each entity can be passive and listen for session requests from any peer that has a transfer for it. if that's not the case, the polling behavior below has to happen π you can also tweak this so the session stays up as long as any transfers are queued π¦
Active-Only Polling Sessions: some entities can only ever be the active side π§ this happens when the naming or addressing is variable (like a dynamically assigned IP address or domain name), or when firewall or routing rules block incoming TCP connections π₯ for these, sessions also have to be set up when an incoming transfer is expected from a peer, or on a periodic schedule β just know this polling causes inefficiencies compared to as-needed ephemeral sessions π
there's a whole spectrum between a single persistent session and only ephemeral sessions π you can apply different policies to each peer and to each bundle as it gets transferred (for example, for quality of service) π and future session extension types can add even more nuance to session policies and policy negotiation π
3.6. Transfer Segmentation Policies πΈ
okay this one is about how big the chunks of a transfer are π each TCPCL session lets you negotiate a transfer segmentation policy in each direction π the receiver sets its Segment Maximum Receive Unit (MRU) in its SESS_INIT message to say the largest segment it'll accept, and the transmitter can split a transfer into any sizes smaller than that receiver's Segment MRU β¨ the spec says it's a network admin thing to pick a good segmentation policy, but this section gives guidance to steer things toward performance goals π admins are also advised to think about the Segment MRU alongside the chunking/packetization that TLS, TCP, and any intermediate network-layer nodes do π¦
Minimum Overhead: this is for simple networks that trade relatively small bundles π§ you can set the Segment MRU equal to the Transfer MRU, which means every transfer goes out as a single data segment (aka no real segmentation at all) π if the network is closed and every transmitter is known to use a single-segment policy, receivers can skip segment reassembly entirely π«Ά heads up though: this CL runs over a TCP stream, which has a kind of head-of-queue blocking between messages π so while one entity is sending a single XFER_SEGMENT message, it can't send any XFER_ACK or XFER_REFUSE messages for the transfers it has received π
Predictable Message Sizing: if you want the maximum message size tightly controlled π set the Segment MRU to the largest acceptable size (that's the message size minus the XFER_SEGMENT header size), and transmitters can always cut a transfer into maximum-size chunks no bigger than the Segment MRU π this means no single XFER_SEGMENT hogs the TCP stream for too long π otherwise it could block outgoing XFER_ACK and XFER_REFUSE messages for received transfers π
Dynamic Segmentation: even after the Segment MRU is negotiated for each receiving entity, the actual segmentation only has to make sure each individual segment is no bigger than that MRU πΈ if TCP throughput is dynamic, the segment size can be dynamic too, so you can keep message transmission duration under control β¨
and there's a whole range of policies between minimum overhead (big MRU, single segment) and predictable message sizing (small MRU, heavily segmented) π¦ you can apply different policies to each transfer stream to and from any particular entity, and future session extension and transfer extension types can add even more nuance to transfer policies and policy negotiation π
3.7. Example Message Exchange β¨
Okay so, Figure 15 is giving full walkthrough energy π¬. It shows the session setup and then one bundle chopped into three data segments ("L1", "L2", and "L3") going from Entity A to Entity B π.
Note that the sending entity can send multiple XFER_SEGMENT messages without waiting for the matching XFER_ACK responses π. That's pipelining on a transfer stream, and it's so efficient, ngl. The example only shows one bundle, but you can also pipeline XFER_SEGMENT messages for different bundles without waiting for each XFER_ACK π . What you can't do is interleave data segments from different bundles π .
No errors or rejections show up in this example, so it's all good vibes π.
Entity A Entity B
======== ========
+-------------------------+
| Open TCP Connection | -> +-------------------------+
+-------------------------+ <- | Accept Connection |
+-------------------------+
+-------------------------+
| Contact Header | -> +-------------------------+
+-------------------------+ <- | Contact Header |
+-------------------------+
+-------------------------+
| SESS_INIT | -> +-------------------------+
+-------------------------+ <- | SESS_INIT |
+-------------------------+
+-------------------------+
| XFER_SEGMENT (start) | ->
| Transfer ID [I1] |
| Length [L1] |
| Bundle Data 0..(L1-1) |
+-------------------------+
+-------------------------+ +-------------------------+
| XFER_SEGMENT | -> <- | XFER_ACK (start) |
| Transfer ID [I1] | | Transfer ID [I1] |
| Length [L2] | | Length [L1] |
|Bundle Data L1..(L1+L2-1)| +-------------------------+
+-------------------------+
+-------------------------+ +-------------------------+
| XFER_SEGMENT (end) | -> <- | XFER_ACK |
| Transfer ID [I1] | | Transfer ID [I1] |
| Length [L3] | | Length [L1+L2] |
|Bundle Data | +-------------------------+
| (L1+L2)..(L1+L2+L3-1)|
+-------------------------+
+-------------------------+
<- | XFER_ACK (end) |
| Transfer ID [I1] |
| Length [L1+L2+L3] |
+-------------------------+
+-------------------------+
| SESS_TERM | -> +-------------------------+
+-------------------------+ <- | SESS_TERM |
+-------------------------+
+-------------------------+ +-------------------------+
| TCP Close | -> <- | TCP Close |
+-------------------------+ +-------------------------+
Figure 15: An Example of the Flow of Protocol Messages on a
Single TCP Session between Two Entities
4. Session Establishment π
Bestie, before any bundles can move over the TCPCL, a TCPCL session MUST first be established between the communicating entities π«Ά. It's up to the implementation to decide how and when session setup gets triggered π€·. Some sessions can be opened proactively and kept alive for as long as the network conditions allow, while others only open when a bundle is queued for transmission and the routing algorithm picks a certain next-hop node π¦.
4.1. TCP Connection π
To set up a TCPCL session, an entity MUST first establish a TCP connection with the intended peer entity, typically by using the services provided by the operating system π. Destination port number 4556 has been assigned by IANA as the registered port number for the TCPCL; see Section 8.1. Other destination port numbers MAY be used per local configuration π. Figuring out a peer's destination port number (if it's different from the registered TCPCL port) is left up to the implementation. Any source port number MAY be used for TCPCL sessions. Typically, an operating system assigned number in the TCP Ephemeral range (49152-65535) gets used.
If the entity can't establish a TCP connection for any reason, handling that failure is an implementation matter π. An entity MAY decide to reattempt the connection. If it does, it MUST NOT overwhelm its target with repeated connection attempts π. So the entity MUST NOT retry the connection setup earlier than some delay time after the last attempt, and it SHOULD use a (binary) exponential backoff mechanism to increase that delay when failures keep happening π. The upper limit on a reattempt backoff is implementation defined, but it SHOULD be no longer than one minute (60 seconds) before signaling to the BPA that a connection cannot be made β°.
Once a TCP connection is established, the active entity SHALL immediately transmit its Contact Header π¨. The passive entity SHALL wait for the active entity's Contact Header. When a Contact Header comes in, the passive entity SHALL transmit its own Contact Header. If either entity doesn't receive a Contact Header after some implementation-defined time duration following the TCP connection, the waiting entity SHALL close the TCP connection πͺ. Entities SHOULD choose a Contact Header reception timeout interval no longer than one minute (60 seconds). The ordering here is so smart: the passive entity doesn't allocate resources to a potential TCPCL session until a valid Contact Header has arrived from the active entity π§ . This ordering also lets the passive peer adapt to alternate TCPCL protocol versions π¦.
The format of the Contact Header is described in Section 4.2. Because the TCPCL protocol version in use is part of the initial Contact Header, entities using TCPCL version 4 can coexist on a network with entities using earlier TCPCL versions π€. Some negotiation is needed for interoperation, as described in Section 4.3.
Within this specification, when an entity is said to "close" a TCP connection, the entity SHALL use the TCP FIN mechanism and not the RST mechanism π . Either mechanism, when received, will still cause a TCP connection to become closed.
4.2. Contact Header π§Ύ
This section describes the format of the Contact Header and what its fields mean π.
If the entity is configured to enable the exchange of messages according to TLS 1.3 [RFC8446] or any successors compatible with that TLS ClientHello, the CAN_TLS flag within its Contact Header SHALL be set to 1 π. The RECOMMENDED policy is to enable TLS for all sessions, even if security policy doesn't allow or require authentication. This follows the "opportunistic security" model specified in [RFC7435], though an active attacker could interfere with the exchange in such cases (see Section 7.4) π.
Upon receipt of the Contact Header, both entities perform the validation and negotiation procedures defined in Section 4.3. After receiving the Contact Header from the other entity, either entity MAY refuse the session by sending a SESS_TERM message with an appropriate reason code π ββοΈ.
The format for the Contact Header looks like this:
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 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
+---------------+---------------+---------------+---------------+
| magic='dtn!' |
+---------------+---------------+---------------+---------------+
| Version | Flags |
+---------------+---------------+
Figure 16: Contact Header Format
See Section 4.3 for details on how to use each of these Contact Header fields π§©.
The fields of the Contact Header are as follows:
magic: A four-octet field that always contains the octet sequence0x64 0x74 0x6E 0x21, i.e., the text string "dtn!" in US-ASCII (and UTF-8) πΈ.Version: A one-octet field value containing the value4(current version of the TCPCL protocol) β.Flags: A one-octet field of single-bit flags, interpreted according to the descriptions in Table 1. All reserved header flag bits SHALL be set to 0 by the sender. All reserved header flag bits SHALL be ignored by the receiver π¦.
+==========+========+===========================================+
| Name | Code | Description |
+==========+========+===========================================+
| CAN_TLS | 0x01 | If this bit is set, it indicates that the |
| | | sending peer has enabled TLS security. |
+----------+--------+-------------------------------------------+
| Reserved | others | |
+----------+--------+-------------------------------------------+
Table 1: Contact Header Flags
4.3. Contact Validation and Negotiation π
okay so, the moment a Contact Header lands, both sides run through these checks to make sure the TCPCL session is legit and to agree on the session parameters. bestie, this part is lowkey the handshake drama π
If the "magic string" is not present or is not valid, the connection MUST be terminated. The whole point of the magic string is to add a little protection against someone accidentally TCP-connecting with a different protocol than this one π To stop a misconfigured app from flooding you with repeated connections, a passive entity MAY deny new TCP connections from a specific peer address for a period of time after one or more connections fail to provide a decodable Contact Header. π
The first negotiation figures out which TCPCL protocol version to use. The active entity always sends its Contact Header first and then waits for a response from the passive entity. During contact initiation, the active TCPCL entity SHALL send the highest TCPCL protocol version on a first session attempt for a TCPCL peer. If the active entity receives a Contact Header with a lower protocol version than the one it sent earlier on the TCP connection, the TCP connection SHALL be closed. If the active entity receives a SESS_TERM message with a reason code of "Version mismatch", that entity MAY attempt further TCPCL sessions with the peer using earlier protocol version numbers in decreasing order. Managing multi-TCPCL-session state such as this is an implementation matter. π§©
If the passive entity receives a Contact Header containing a version that is not a version of the TCPCL protocol that the entity implements, then the entity SHALL send its Contact Header and immediately terminate the session with a reason code of "Version mismatch". If the passive entity receives a Contact Header with a version that is lower than the latest version of the protocol that the entity implements, the entity MAY either terminate the session (with a reason code of "Version mismatch") or adapt its operation to conform to the older version of the protocol. The decision of version fallback is an implementation matter. π
The negotiated contact parameters defined by this specification are described in the following paragraphs. β¨
- TCPCL Version: Both Contact Headers of a successful contact negotiation have identical TCPCL version numbers as described above. Only upon response of a Contact Header from the passive entity is the TCPCL protocol version established and session negotiation begun. π
- Enable TLS: Negotiation of the Enable TLS parameter is performed by taking the logical AND of the two Contact Headers'
CAN_TLSflags. A local security policy is then applied to determine whether the negotiated value of Enable TLS is acceptable. A reasonable security policy would require or disallow the use of TLS, depending upon the desired network flows. The RECOMMENDED policy is to require TLS for all sessions, even if security policy does not allow or require authentication. Because this state is negotiated over an unsecured medium, there is a risk of TLS Stripping as described in Section 7.4. π
If the Enable TLS state is unacceptable, the entity SHALL terminate the session with a reason code of "Contact Failure". Note that this "Contact Failure" reason is different than a failure of a TLS handshake or TLS authentication after an agreed-upon and acceptable Enable TLS state. If the negotiated Enable TLS value is "true" and acceptable, then the TLS negotiation feature described in Section 4.4 begins immediately following the Contact Header exchange. π
4.4. Session Security π
This version of the TCPCL protocol supports establishing a TLS session within an existing TCP connection. When TLS is used within the TCPCL, it affects the entire session. Once TLS is established, there is no mechanism available to downgrade the TCPCL session to non-TLS operation. π«β¬οΈ
Once established, the lifetime of a TLS connection SHALL be bound to the lifetime of the underlying TCP connection. Immediately prior to actively ending a TLS connection after TCPCL session termination, the peer that sent the original (non-reply) SESS_TERM message SHOULD follow the closure alert procedure provided in [RFC8446] to cleanly terminate the TLS connection. Because each TCPCL message is either fixed length or self-indicates its length, the lack of a TLS closure alert will not cause data truncation or corruption. π§Ό
Subsequent TCPCL session attempts to the same passive entity MAY attempt to use the TLS session resumption feature. There is no guarantee that the passive entity will accept the request to resume a TLS session, and the active entity cannot assume any resumption outcome. π€
4.4.1. Entity Identification πͺͺ
The TCPCL uses TLS for certificate exchange in both directions to identify each entity and to allow each entity to authenticate its peer. Each certificate can potentially identify multiple entities, and there is no problem using such a certificate as long as the identifiers are sufficient to meet authentication policy (as described in later sections) for the entity that presents it. π
Because the PKIX environment of each TCPCL entity is likely not controlled by the certificate end users (see Section 3.4), the TCPCL defines a prioritized list of what a certificate can identify regarding a TCPCL entity: π
- Node ID: The ideal certificate identity is the node ID of the entity using the NODE-ID, as defined below. When the node ID is identified, there is no need for any lower-level identification to be present (though it can still be present, and if so it is also validated). π
- DNS Name: If CA policy forbids a certificate to contain an arbitrary NODE-ID but allows a DNS-ID to be identified, then one or more stable DNS names can be identified in the certificate. The use of wildcard DNS-IDs is discouraged due to the complex rules for matching and dependence on implementation support for wildcard matching (see Section 6.4.3 of [RFC6125]). π
- Network Address: If no stable DNS name is available but a stable network address is available and CA policy allows a certificate to contain an IPADDR-ID (as defined below), then one or more network addresses can be identified in the certificate. π
This specification defines a NODE-ID of a certificate as being the subjectAltName entry of type otherName with a name form of BundleEID (see Section 4.4.2.1) and a value limited to a node ID. An entity SHALL ignore any entry of type otherName with a name form of BundleEID and a value that is some URI other than a node ID. The NODE-ID is similar to the URI-ID as defined in [RFC6125] but is restricted to a node ID rather than a URI with a qualified-name authority part. Unless specified otherwise by the definition of the URI scheme being authenticated, URI matching of a NODE-ID SHALL use the URI comparison logic provided in [RFC3986] and scheme-based normalization of those schemes specified in [RFC9171]. A URI scheme can refine this "exact match" logic with rules regarding how node IDs within that scheme are to be compared with the certificate-authenticated NODE-ID. π§
This specification reuses the DNS-ID definition in Section 1.8 of [RFC6125], which is the subjectAltName entry of type dNSName whose value is encoded according to [RFC5280]. π
This specification defines an IPADDR-ID of a certificate as being the subjectAltName entry of type iPAddress whose value is encoded according to [RFC5280]. π
4.4.2. Certificate Profile for the TCPCL π
All end-entity certificates used by a TCPCL entity SHALL conform to [RFC5280], or any updates or successors to that profile. When an end-entity certificate is supplied, the full certification chain SHOULD be included unless security policy indicates that is unnecessary. An entity SHOULD omit the root CA certificate (the last item of the chain) when sending a certification chain, as the recipient already has the root CA to anchor its validation. π
The TCPCL requires version 3 certificates due to the extensions used by this profile. TCPCL entities SHALL reject as invalid version 1 and version 2 end-entity certificates. π·
TCPCL entities SHALL accept certificates that contain an empty Subject field or contain a Subject without a Common Name. Identity information in end-entity certificates is contained entirely in the subjectAltName extension as defined in Section 4.4.1 and discussed in the paragraphs below. π«Ά
All end-entity and CA certificates used for the TCPCL SHOULD contain both a subject key identifier and an authority key identifier extension in accordance with [RFC5280]. TCPCL entities SHOULD NOT rely on either a subject key identifier or an authority key identifier being present in any received certificate. Including key identifiers simplifies the work of an entity that needs to assemble a certification chain. π§©
Unless prohibited by CA policy, a TCPCL end-entity certificate SHALL contain a NODE-ID that authenticates the node ID of the peer. When assigned one or more stable DNS names, a TCPCL end-entity certificate SHOULD contain a DNS-ID that authenticates those (fully qualified) names. When assigned one or more stable network addresses, a TCPCL end-entity certificate MAY contain an IPADDR-ID that authenticates those addresses. π·οΈ
When allowed by CA policy, a Bundle Protocol Security (BPSec; see [RFC9172]) end-entity certificate SHOULD contain a PKIX Extended Key Usage (EKU) extension in accordance with Section 4.2.1.12 of [RFC5280]. When the PKIX EKU extension is present, it SHOULD contain the key purpose id-kp-bundleSecurity (see Section 4.4.2.1). Although not specifically required by the TCPCL, some networks or TLS implementations assume that id-kp-clientAuth and id-kp-serverAuth need to be used for the client side and the server side of TLS authentication, respectively. For interoperability, a TCPCL end-entity certificate MAY contain an EKU with both id-kp-clientAuth and id-kp-serverAuth values. π€
When allowed by CA policy, a TCPCL end-entity certificate SHOULD contain a PKIX key usage extension in accordance with Section 4.2.1.3 of [RFC5280]. The PKIX key usage bit that is consistent with TCPCL security using TLS 1.3 is digitalSignature. The specific algorithms used during the TLS handshake will determine which of those key uses are exercised. Earlier versions of TLS can mandate the use of the keyEncipherment bit or the keyAgreement bit. π
When allowed by CA policy, a TCPCL end-entity certificate SHOULD contain an Online Certificate Status Protocol (OCSP) URI within an authority information access extension in accordance with Section 4.2.2.1 of [RFC5280]. π°οΈ
4.4.2.1. PKIX OID Allocations
okay so this part is where we hand out the ID badges πͺͺ. This document defines a PKIX Other Name Form identifier, id-on-bundleEID, in Appendix B π. You can use it as the type-id in a subjectAltName entry of type otherName. The BundleEID value tied to the id-on-bundleEID otherName type-id SHALL be a URI, encoded as an IA5String, with a scheme that is present in the IANA "Bundle Protocol URI Scheme Types" registry [IANA-BUNDLE]. Even though this Other Name Form lets any endpoint ID show up, the NODE-ID defined in Section 4.4.1 limits its use to contain only a node ID π.
This document also defines a PKIX EKU key purpose, id-kp-bundleSecurity, in Appendix B π. This purpose can be used to restrict a certificate's use. The id-kp-bundleSecurity purpose can be combined with other purposes in the same certificate β¨.
4.4.3. TLS Handshake
TLS gets negotiated through the Contact Header, as explained in Section 4.3 π€. After you negotiate an Enable TLS parameter of "true", and before any other TCPCL messages get sent within the session, the session entities SHALL begin a TLS handshake in accordance with [RFC8446]. By convention, this protocol uses the entity that initiated the underlying TCP connection (the active peer) as the "client" role of the TLS handshake request π¦.
The TLS handshake, if it happens, counts as part of the contact negotiation before the TCPCL session is actually established πΈ. Details about exposure of sensitive data are covered in Section 7.
The parameters inside each TLS negotiation are implementation dependent, but any TCPCL entity SHALL follow all recommended practices specified in BCP 195 [RFC7525], or any updates or successors that become part of BCP 195. Within each TLS handshake, the following requirements apply (roughly in the order they happen) π :
- ClientHello: When a resolved DNS name was used to establish the TCP connection, the TLS ClientHello SHOULD include a
server_nameextension in accordance with [RFC6066]. When present, theserver_nameextension SHALL contain aHostNamevalue taken from the DNS name (of the passive entity) that was resolved.
Note: TheHostNamein theserver_nameextension is the network name for the passive entity, not the node ID of that entity. π§
- Server Certificate: The passive entity SHALL supply a certificate within the TLS handshake to allow authentication of its side of the session. The supplied end-entity certificate SHALL conform to the profile described in Section 4.4.2. The passive entity MAY use the SNI DNS name to choose an appropriate server-side certificate that authenticates that DNS name.
- Certificate Request: During the TLS handshake, the passive entity SHALL request a client-side certificate.
- Client Certificate: The active entity SHALL supply a certificate chain within the TLS handshake to allow authentication of its side of the session. The supplied end-entity certificate SHALL conform to the profile described in Section 4.4.2.
If a TLS handshake cannot negotiate a TLS connection, both entities of the TCPCL session SHALL close the TCP connection π. At this point the TCPCL session has not yet been established, so there is no TCPCL session to terminate.
After a TLS connection is successfully established, the active entity SHALL send a SESS_INIT message to begin session negotiation. This session negotiation and all subsequent messaging are secured π₯.
4.4.4. TLS Authentication
Using PKIX certificates exchanged during the TLS handshake, each of the entities can authenticate a peer node ID directly, or authenticate the peer DNS name or network address. The logic for handling certificates and certificate data is split into these phases π§©:
- Validating the certification path from the end-entity certificate up to a trusted root CA.
- Validating the EKU and other properties of the end-entity certificate.
- Authenticating identities from a valid end-entity certificate.
- Applying security policy to the result of each identity type authentication.
The result of validating a peer identity (see Section 4.4.1) against one or more types of certificate claims is one of the following:
- Absent: Indicating that no such claims are present in the certificate and the identity cannot be authenticated.
- Success: Indicating that one or more such claims are present and at least one matches the peer identity value.
- Failure: Indicating that one or more such claims are present and none match the peer identity.
4.4.4.1. Certificate Path and Purpose Validation
For any peer end-entity certificate received during the TLS handshake, the entity SHALL perform the certification path validation described in [RFC5280] up to one of the entity's trusted CA certificates. If enabled by local policy, the entity SHALL perform an OCSP check of each certificate providing OCSP authority information in accordance with [RFC6960]. If certificate validation fails or if security policy disallows a certificate for any reason, the entity SHALL fail the TLS handshake with a bad_certificate alert. Leaving out part of the certification chain can cause the entity to fail to validate a certificate if the certificates that were left out are unknown to the entity (see Section 7.6) π.
For the end-entity peer certificate received during the TLS handshake, the entity SHALL apply security policy to the key usage extension (if present) and EKU extension (if present) in accordance with Sections 4.2.1.12 and 4.2.1.3 of [RFC5280], respectively, and with the profile discussed in Section 4.4.2 of this document π.
4.4.4.2. Network-Level Authentication
Either during or immediately after the TLS handshake, each entity, if required by security policy, SHALL validate the following certificate identifiers together in accordance with Section 6 of [RFC6125]:
- If the active entity resolved a DNS name (of the passive entity) in order to initiate the TCP connection, that DNS name SHALL be used as a DNS-ID reference identifier.
- The IP address of the other side of the TCP connection SHALL be used as an IPADDR-ID reference identifier.
If the network-level identifier's authentication result is Failure, or if the result is Absent and security policy requires an authenticated network-level identifier, the entity SHALL terminate the session (with a reason code of "Contact Failure") π.
4.4.4.3. Node ID Authentication
Immediately before session parameter negotiation, each entity, if required by security policy, SHALL validate the certificate NODE-ID in accordance with Section 6 of [RFC6125] using the node ID of the peer's SESS_INIT message as the NODE-ID reference identifier. If the NODE-ID validation result is Failure, or if the result is Absent and security policy requires an authenticated node ID, the entity SHALL terminate the session (with a reason code of "Contact Failure") π.
4.4.5. Policy Recommendations
A RECOMMENDED security policy encompasses the following π:
- enabling the use of OCSP checking during the TLS handshake.
- instructing that, if an EKU extension is present, the extension needs to contain
id-kp-bundleSecurity(Section 4.4.2.1) to be usable with TCPCL security. - requiring a validated node ID (Section 4.4.4.3) and ignoring any network-level identifier (Section 4.4.4.2).
This policy relies on and informs the certificate requirements provided in Section 4.4.3. It also assumes that a DTN-aware CA (see Section 3.4) will only issue a certificate for a node ID when it has verified that the private key holder actually controls the bundle node. This is needed to avoid the threat identified in Section 7.9 β οΈ. This policy requires that a certificate contain a NODE-ID and allows the certificate to also contain network-level identifiers. A tailored policy on a more controlled network could relax the requirement on node ID validation and allow just network-level identifiers to authenticate a peer πΈ.
4.4.6. Example TLS Initiation
A summary of a typical TLS initiation is shown in the sequence in Figure 17 below. In this example, the active peer terminates the session, but termination can be initiated from either peer π¬.
Entity A Entity B
active peer passive peer
+-------------------------+
| Open TCP Connection | -> +-------------------------+
+-------------------------+ <- | Accept Connection |
+-------------------------+
+-------------------------+
| Contact Header | -> +-------------------------+
+-------------------------+ <- | Contact Header |
+-------------------------+
+-------------------------+ +-------------------------+
| TLS Negotiation | -> <- | TLS Negotiation |
| (as client) | | (as server) |
+-------------------------+ +-------------------------+
DNS-ID and IPADDR-ID authentication occurs.
Secured TCPCL messaging can begin.
+-------------------------+
| SESS_INIT | -> +-------------------------+
+-------------------------+ <- | SESS_INIT |
+-------------------------+
NODE-ID authentication occurs.
Session is established, transfers can begin.
+-------------------------+
| SESS_TERM | -> +-------------------------+
+-------------------------+ <- | SESS_TERM |
+-------------------------+
+-------------------------+
| TLS Closure Alert | -> +-------------------------+
+-------------------------+ <- | TLS Closure Alert |
+-------------------------+
+-------------------------+ +-------------------------+
| TCP Close | -> <- | TCP Close |
+-------------------------+ +-------------------------+
Figure 17: A Simple Visual Example of TCPCL TLS Establishment
between Two Entities
4.5. Message Header β¨
okay so once the Contact Header has been swapped and (if TLS got negotiated) the TLS handshake is done, every message sent over the session starts with a one-octet header. bestie, it's giving minimalist π
0 1 2 3 4 5 6 7
+---------------+
| Message Type |
+---------------+
Figure 18: Format of the Message Header
The Message Header has just one field, and it's the cutest π
Message Type: tells you what kind of message this is. It's listed in Table 2 below, and the encoded values live in Section 8.5. π¦
+==============+======+=====================================+
| Name | Code | Description |
+==============+======+=====================================+
| SESS_INIT | 0x07 | Contains the session parameter |
| | | inputs from one of the entities, as |
| | | described in Section 4.6. |
+--------------+------+-------------------------------------+
| SESS_TERM | 0x05 | Indicates that one of the entities |
| | | participating in the session wishes |
| | | to cleanly terminate the session, |
| | | as described in Section 6.1. |
+--------------+------+-------------------------------------+
| XFER_SEGMENT | 0x01 | Indicates the transmission of a |
| | | segment of bundle data, as |
| | | described in Section 5.2.2. |
+--------------+------+-------------------------------------+
| XFER_ACK | 0x02 | Acknowledges reception of a data |
| | | segment, as described in |
| | | Section 5.2.3. |
+--------------+------+-------------------------------------+
| XFER_REFUSE | 0x03 | Indicates that the transmission of |
| | | the current bundle SHALL be |
| | | stopped, as described in |
| | | Section 5.2.4. |
+--------------+------+-------------------------------------+
| KEEPALIVE | 0x04 | Used to keep the TCPCL session |
| | | active, as described in |
| | | Section 5.1.1. |
+--------------+------+-------------------------------------+
| MSG_REJECT | 0x06 | Contains a TCPCL message rejection, |
| | | as described in Section 5.1.2. |
+--------------+------+-------------------------------------+
Table 2: TCPCL Message Types
4.6. Session Initialization Message (SESS_INIT) π
Before a session is set up and ready to move bundles, the entities have to negotiate the session parameters π«Ά The SESS_INIT message carries each entity's own parameters, and those get combined to work out the per-session parameters, as described in Section 4.7. β¨
Here's what a SESS_INIT message looks like:
+-----------------------------+
| Message Header |
+-----------------------------+
| Keepalive Interval (U16) |
+-----------------------------+
| Segment MRU (U64) |
+-----------------------------+
| Transfer MRU (U64) |
+-----------------------------+
| Node ID Length (U16) |
+-----------------------------+
| Node ID Data (variable) |
+-----------------------------+
| Session Extension |
| Items Length (U32) |
+-----------------------------+
| Session Extension |
| Items (var.) |
+-----------------------------+
Figure 19: SESS_INIT Format
Now the fields, one by one πΈ
Keepalive Interval: a 16-bit unsigned integer giving the minimum interval, in seconds, to negotiate as the Session Keepalive, using the method in Section 4.7.
Segment MRU: a 64-bit unsigned integer for the biggest single-segment data payload this entity can receive in this session. Any XFER_SEGMENT sent to this peer SHALL have a data payload no longer than the peer's Segment MRU. The two entities in one session MAY have different Segment MRUs, and there's no rule that says they have to match. π
Transfer MRU: a 64-bit unsigned integer for the biggest total-bundle data size this entity can receive in this session. Any bundle transfer sent to this peer SHALL have a Total Bundle Length payload no longer than the peer's Transfer MRU. This value can be used to do proactive bundle fragmentation. Again, the two entities MAY have different Transfer MRUs, and no relationship between the two is required. π§
Node ID Length and Node ID Data: these two fields together make up a variable-length text string. The Node ID Length is a 16-bit unsigned integer that counts the octets of Node ID Data coming after it. A zero-length node ID SHALL be used to mean "no node ID at all," which is different from a truly empty node ID. This lets an entity avoid spilling node ID info on an untrusted network, which is so smart π A non-zero-length Node ID Data SHALL contain the UTF-8 encoded node ID of the entity that sent the SESS_INIT message. Every node ID SHALL be a URI that follows the requirements in [RFC3986] and uses a URI scheme from the IANA "Bundle Protocol URI Scheme Types" registry [IANA-BUNDLE]. The node ID itself can be authenticated as described in Section 4.4.4. π
Session Extension Items Length and Session Extension Items list: together these carry protocol extension data that this specification doesn't define. The Session Extension Items Length is the total number of octets that follow and are used to encode the Session Extension Items list. Each Session Extension Item is encoded inside a consistent data container, as described in Section 4.8. The full set of Session Extension Items applies for the whole TCPCL session. The order and multiplicity of these items matter, as defined in the associated type specification(s). If the content of the Session Extension Items list doesn't match the Session Extension Items Length (for example, the last item claims more or fewer octets than the Session Extension Items Length says), then the reception of the SESS_INIT is considered to have failed. π
If an entity gets a peer node ID that isn't authenticated (by the procedure in Section 4.4.4.3), that node ID SHOULD NOT be used by a BPA for any discovery or routing functions. Trusting an unauthenticated node ID can lead to the threat described in Section 7.9. This part is seriously important, so please don't skip it π
When the active entity starts a TCPCL session, it's likely doing so based on routing information that ties a node ID to the CL parameters used to start the session. If the active entity gets a SESS_INIT with a different node ID than the one it intended for the TCPCL session, the session MAY be allowed to be established. If it is allowed, that session SHALL be associated with the node ID provided in the SESS_INIT message, not the intended value. π¦
4.7. Session Parameter Negotiation β¨
An entity works out the parameters for a TCPCL session by negotiating its own preferences (the ones it sent in its SESS_INIT to the peer) against the preferences of the peer (the ones in the SESS_INIT it received). The negotiated parameters defined by this specification are described in the paragraphs below. It's like a little group decision π
Transfer MTU and Segment MTU: the Maximum Transmission Unit (MTU) for whole transfers and for individual segments is the same as the Transfer MRU and Segment MRU, respectively, from the received SESS_INIT message. A transmitting peer can send individual segments of any size smaller than the Segment MTU, depending on local policy, dynamic network conditions, and so on. Deciding the size of each transmitted segment is up to the implementation π If either the Transfer MRU or the Segment MRU is unacceptable, the entity SHALL terminate the session with a reason code of "Contact Failure". π
Session Keepalive: the Session Keepalive is negotiated by taking the minimum of the two Keepalive Interval values from the two SESS_INIT messages. The Session Keepalive Interval controls the behavior described in Section 5.1.1. If the Session Keepalive Interval is unacceptable, the entity SHALL terminate the session with a reason code of "Contact Failure". β
Note: A negotiated Session Keepalive of zero indicates that KEEPALIVEs are disabled. π
Once this parameter negotiation is done, the protocol doesn't define any other way to change the parameters of an established session. If you want a change, the TCPCL session MUST be terminated and a new session established. Literally no shortcuts, bestie π
4.8. Session Extension Items β¨
okay so every Session Extension Item SHALL be wrapped in the exact same Type-Length-Value (TLV) container, like the one in Figure 20 π
Here's what each field in the Session Extension Item does π
- Item Flags: a one-octet field of generic bit flags for the Item, all listed in Table 3 π© Every reserved header flag bit SHALL be set to 0 by the sender, and every reserved header flag bit SHALL be ignored by the receiver. Now the big drama: if a TCPCL entity gets a Session Extension Item with an Item Type it doesn't recognize AND the CRITICAL flag is set to 1, that entity SHALL terminate the TCPCL session with a SESS_TERM reason code of "Contact Failure" π But if the CRITICAL flag is 0, the entity SHALL skip over and ignore any item with an unknown Item Type π«Ά
- Item Type: a 16-bit unsigned integer naming the type of extension item π§ This specification doesn't define any extension types itself, but it does set up an IANA registry for these codes (see Section 8.3) πΈ
- Item Length: a 16-bit unsigned integer telling you how many Item Value octets come next π
- Item Value: a variable-length data field, read according to its Item Type. This specification puts no restrictions on how an extension uses the Item Value data π Extension specifications SHOULD avoid large data lengths, though, because no bundle transfers can start until the full extension data has been sent π
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 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
+---------------+---------------+---------------+---------------+
| Item Flags | Item Type | Item Length...|
+---------------+---------------+---------------+---------------+
| length contd. | Item Value... |
+---------------+---------------+---------------+---------------+
Figure 20: Session Extension Item Format
+==========+========+==================================+
| Name | Code | Description |
+==========+========+==================================+
| CRITICAL | 0x01 | If this bit is set, it indicates |
| | | that the receiving peer must |
| | | handle the extension item. |
+----------+--------+----------------------------------+
| Reserved | others | |
+----------+--------+----------------------------------+
Table 3: Session Extension Item Flags
5. Established Session Operation π¦
This section is all about what happens for the whole life of an established session, including how bundles actually get sent across it π
5.1. Upkeep and Status Messages π·
5.1.1. Session Upkeep (KEEPALIVE) π
The protocol has a built-in provision for sending KEEPALIVE messages over the TCPCL session, which helps figure out whether the underlying TCP connection has been disrupted π
Remember the Session Keepalive Interval from Section 4.7? It's one of the parameters negotiated for each session β¨ If the negotiated Session Keepalive is zero (meaning one or both SESS_INIT messages contain a zero Keepalive Interval), then keepalive is disabled π ββοΈ There's no logical minimum for the Keepalive Interval (other than whatever the positive-value encoding forces), but if you're running lots of sessions over an open, shared network, a short interval could cause excessive traffic π¦ So for shared network use, entities SHOULD choose a Keepalive Interval no shorter than 30 seconds π«Ά There's also no logical maximum (other than the fixed-size encoding's limit), but an idle TCP connection is liable to be closed by the host operating system if the keepalive time is longer than tens of minutes π± That's why entities SHOULD choose a Keepalive Interval no longer than 10 minutes (600 seconds) β°
The chosen Keepalive Interval SHOULD NOT be too short, because TCP retransmissions may happen when packets get lost π₯Ί Those retransmissions have to be triggered by a timeout (the TCP retransmission timeout (RTO)), which depends on the measured RTT for the TCP connection, so KEEPALIVE messages can end up experiencing noticeable latency π’
A KEEPALIVE message is just a one-octet Message Type code of KEEPALIVE (as described in Table 2) with no additional data π Both sides SHALL send a KEEPALIVE message whenever the negotiated interval has elapsed with no transmission of any message (KEEPALIVE or otherwise) π
If no message (KEEPALIVE or otherwise) has been received in a session after some implementation-defined time duration, then the entity SHALL terminate the session by transmitting a SESS_TERM message (as described in Section 6.1) with a reason code of "Idle timeout" πͺ If the idle timeout is configurable, its duration SHOULD be no shorter than twice the Keepalive Interval. If it isn't configurable, the idle timeout duration SHOULD be exactly twice the Keepalive Interval π°οΈβ¨
5.1.2. Message Rejection (MSG_REJECT) π
This message type isn't expected to show up in a well-functioning session π Its whole purpose is troubleshooting bad entity behavior, letting the peer see why an entity isn't responding the way it expected to its messages π
If a TCPCL entity receives a message type it doesn't know (maybe because of an unhandled protocol version mismatch, or a session extension that got negotiated incorrectly and defines a new message type), the entity SHALL send a MSG_REJECT message with a reason code of "Message Type Unknown" and then close the TCP connection π« If a TCPCL entity receives a message type it does know, but that's inappropriate for the negotiated session parameters (possibly because of an incorrectly negotiated session extension), the entity SHALL send a MSG_REJECT message with a reason code of "Message Unsupported" π And if a TCPCL entity receives a message that's inappropriate for the current session state (for example, a SESS_INIT after the session is already established, or a XFER_ACK message with an unknown Transfer ID), the entity SHALL send a MSG_REJECT message with a reason code of "Message Unexpected" π
The MSG_REJECT message format is shown in Figure 21 π§©
+-----------------------------+
| Message Header |
+-----------------------------+
| Reason Code (U8) |
+-----------------------------+
| Rejected Message Header |
+-----------------------------+
Figure 21: Format of MSG_REJECT Messages
The MSG_REJECT fields work like this:
- Reason Code: a one-octet refusal reason code, interpreted using the descriptions in Table 4 π
- Rejected Message Header: a copy of the Message Header of the message that the MSG_REJECT message is being sent back in response to πͺ
+==============+======+========================================+
| Name | Code | Description |
+==============+======+========================================+
| Message Type | 0x01 | A message was received with a Message |
| Unknown | | Type code unknown to the TCPCL entity. |
+--------------+------+----------------------------------------+
| Message | 0x02 | A message was received, but the TCPCL |
| Unsupported | | entity cannot comply with the message |
| | | contents. |
+--------------+------+----------------------------------------+
| Message | 0x03 | A message was received while the |
| Unexpected | | session is in a state in which the |
| | | message is not expected. |
+--------------+------+----------------------------------------+
Table 4: MSG_REJECT Reason Codes
5.2. Bundle Transfer π¦
Everything in this section is directly tied to moving a bundle between TCPCL entities π
A single TCPCL transfer means one bundle gets exchanged between two entities. The convergence layer treats that bundle as opaque data π«§ To do a transfer, the TCPCL chops a bundle up into "segments" sized by the receiving side's Segment MRU (which is defined in Section 4.6) βοΈ How long the segments are is an implementation matter, but each segment MUST NOT be larger than the receiving entity's Segment MRU π The first segment of a bundle is marked with the START flag, and the last one is marked with the END flag π
A single transfer (and, by extension, a single segment) SHALL NOT contain data from more than one bundle π ββοΈ This requirement is put on the agent using the TCPCL, not on the TCPCL itself π§
If multiple bundles get sent over one TCPCL connection, they MUST be sent consecutively, with no interleaving of segments from different bundles π«π No cutting in line, bestie πββοΈ
5.2.1. Bundle Transfer ID πͺͺ
Every bundle transfer message carries a Transfer ID, which is how the messages from both sides of a transfer get matched up to each bundle π§΅ A Transfer ID doesn't try to guarantee uniqueness of the bundle data itself, and it has nothing to do with things like bundle fragmentation π Each time the BPA asks the TCPCL to send a bundle (fragmentary or not), that kicks off a single TCPCL transfer π Each transfer involves sending some number of XFER_SEGMENT and XFER_ACK messages, all correlated by the same Transfer ID π The sending entity makes up the Transfer ID, and the receiving entity reuses that same Transfer ID in its acknowledgments π«Ά
Transfer IDs from each entity SHALL be unique within a single TCPCL session. If the entire 64-bit Transfer ID space runs out, the sending entity SHALL terminate the session with a SESS_TERM reason code of "Resource Exhaustion" πͺ« For bidirectional bundle transfers, a TCPCL entity SHOULD NOT rely on any relationship between the Transfer IDs coming from each side of the TCPCL session π ββοΈ
There's no strict requirement for the starting Transfer ID values or for how Transfer IDs are ordered (see Section 7.13) π€·ββοΈ Still, if there's no other mechanism for generating Transfer IDs, an entity SHALL use this algorithm: the initial Transfer ID from each entity is zero, and each subsequent Transfer ID is the prior one plus one βπ’ Simple, iconic, and easy to debug π
5.2.2. Data Transmission (XFER_SEGMENT) πβ¨
okay so bestie, each bundle gets shipped out in one or more data segments π¦π the layout of an XFER_SEGMENT message is in Figure 22 π¦
+------------------------------+
| Message Header |
+------------------------------+
| Message Flags (U8) |
+------------------------------+
| Transfer ID (U64) |
+------------------------------+
| Transfer Extension |
| Items Length (U32) |
| (only for START segment) |
+------------------------------+
| Transfer Extension |
| Items (var.) |
| (only for START segment) |
+------------------------------+
| Data length (U64) |
+------------------------------+
| Data contents (octet string) |
+------------------------------+
Figure 22: Format of XFER_SEGMENT Messages
here's what each field is giving π
Message Flags π: it's one octet of single-bit flags, read using Table 5 π every reserved header flag bit SHALL be set to 0 by the sender, and every reserved header flag bit SHALL be ignored by the receiver π no drama, just rules
Transfer ID πΈ: a 64-bit unsigned integer that says which transfer this is π§
Transfer Extension Items Length and Transfer Extension Items list π: these two work together as protocol extension data for this spec π they SHALL only be present when the START flag is set to 1 on the message β¨ the Transfer Extension Items Length is the total number of octets that follow and encode the Transfer Extension Items list π¦ each Transfer Extension Item is wrapped in a consistent data container, which you can read about in Section 5.2.5 π«Ά the whole set of items only applies to that one transfer π the order and how many times each item shows up both matter, as spelled out in the type specs for each item π
okay now the important bit πβ οΈ if the contents of the Transfer Extension Items list don't match the Transfer Extension Items Length (like, the last item claims more or fewer octets than the length says), then the reception of the XFER_SEGMENT is considered to have failed π yikes, so double check those numbers, bestie π
Data length π: a 64-bit unsigned integer for how many octets of Data contents are coming next π
Data contents π·: the variable-length data payload of the message π«§
here's Table 5 for the flags π β¨
+==========+========+============================================+
| Name | Code | Description |
+==========+========+============================================+
| END | 0x01 | If this bit is set, it indicates that this |
| | | is the last segment of the transfer. |
+----------+--------+--------------------------------------------+
| START | 0x02 | If this bit is set, it indicates that this |
| | | is the first segment of the transfer. |
+----------+--------+--------------------------------------------+
| Reserved | others | |
+----------+--------+--------------------------------------------+
Table 5: XFER_SEGMENT Flags
so the flags live in the two low-order bits, called START and END in Table 5 π the START flag SHALL be set to 1 when you send the first segment of a transfer π the END flag SHALL be set to 1 when you send the last segment π if the whole transfer fits in a single segment, then both START and END SHALL be set to 1 π it's giving efficiency π₯
and this part is serious, periodt π«Ά once a transfer of a bundle has started, the entity MUST only send segments with sequential portions of that bundle until it sends a segment with END set to 1 π no interleaving of multiple transfers from the same entity is possible inside a single TCPCL session π ββοΈ if you want simultaneous transfers between two entities, you MAY use multiple TCPCL sessions π¦π
5.2.3. Data Acknowledgments (XFER_ACK) π§Ύπ
okay so bestie, TCP is reliable and all, but the usual BSD sockets interface doesn't tell a sending app when the receiving app has actually processed some data π so after sending data, TCPCL needs its own way to check that the receiver got it AND fully processed it π€ that's why the protocol has feedback messages where the receiver sends acknowledgments for the data segments it got π«Άβ¨
the layout of a XFER_ACK message is in Figure 23 πΈ
+-----------------------------+
| Message Header |
+-----------------------------+
| Message Flags (U8) |
+-----------------------------+
| Transfer ID (U64) |
+-----------------------------+
| Acknowledged length (U64) |
+-----------------------------+
Figure 23: Format of XFER_ACK Messages
the fields, bestie π
Message Flags π: one octet of single-bit flags, read using Table 5 π reserved header flag bits SHALL be set to 0 by the sender and SHALL be ignored by the receiver π
Transfer ID πΈ: a 64-bit unsigned integer naming the transfer being acknowledged π§
Acknowledged length π: a 64-bit unsigned integer for the total number of octets in the transfer that are being acknowledged π
now the rules π a receiving TCPCL entity SHALL send a XFER_ACK message in response to each received XFER_SEGMENT message, but only after that segment has been fully processed β¨ the flags in the XFER_ACK header SHALL match the XFER_SEGMENT being acknowledged, including any flags the entity can't decode π¦ the acknowledged length of each XFER_ACK is the sum of the Data length fields of all XFER_SEGMENT messages received so far in that transfer π the sending entity SHOULD send multiple XFER_SEGMENT messages without waiting for the matching XFER_ACK responses π this is what makes pipelining possible on a transfer stream, iconic π π₯
here's an example, bestie π say the sender transmits four segments of bundle data with lengths 100, 200, 500, and 1000 π¦ after the first segment is received, the entity sends an acknowledgment of length 100 π± after the second, it sends one of length 300 π· the third and fourth acknowledgments are of lengths 800 and 1800, respectively π the math is literally so clean ππ
5.2.4. Transfer Refusal (XFER_REFUSE) β¨
Okay so the TCPCL has this move where a receiving entity can basically say "nah, I don't want this bundle" π ββοΈ To do that, after it gets a XFER_SEGMENT message, the entity MAY transmit a XFER_REFUSE message. Since data segments and acknowledgments can totally cross on the wire π, the bundle being refused SHALL be identified by the Transfer ID of the refusal.
Here's the tea π΅: the Transfer MRU is the firm limit on what an entity will accept π , and sending a XFER_REFUSE is NOT locked to it. There's no required relationship between the two. A XFER_REFUSE can be used when the agent's bundle storage is temporarily depleted or somehow constrained π¦. It can also be used after the bundle header or any bundle data gets inspected and judged unacceptable π.
A transfer receiver MAY send a XFER_REFUSE message as soon as it receives any XFER_SEGMENT message. The transfer sender MUST be prepared for this, and MUST associate the refusal with the correct bundle via the Transfer ID fields π«Ά.
The TCPCL itself doesn't have any required behavior for responding to a XFER_REFUSE based on its reason code β¨. The refusal just gets passed up to the BPA as an indication that the transfer has been refused. If a transfer refusal has a reason code that isn't decodable to the BPA, the agent SHOULD treat the refusal as having a reason code of "Unknown" π€.
Here's the format of the XFER_REFUSE message π:
+-----------------------------+
| Message Header |
+-----------------------------+
| Reason Code (U8) |
+-----------------------------+
| Transfer ID (U64) |
+-----------------------------+
Figure 24: Format of XFER_REFUSE Messages
The fields of the XFER_REFUSE message are as follows:
- Reason Code: A one-octet refusal reason code, interpreted according to the descriptions in Table 6. π§Ύ
- Transfer ID: A 64-bit unsigned integer identifying the transfer being refused. π
Here's the reason code table π:
+=============+======+==========================================+
| Name | Code | Description |
+=============+======+==========================================+
| Unknown | 0x00 | The reason for refusal is unknown or is |
| | | not specified. |
+-------------+------+------------------------------------------+
| Completed | 0x01 | The receiver already has the complete |
| | | bundle. The sender MAY consider the |
| | | bundle as completely received. |
+-------------+------+------------------------------------------+
| No | 0x02 | The receiver's resources are exhausted. |
| Resources | | The sender SHOULD apply reactive bundle |
| | | fragmentation before retrying. |
+-------------+------+------------------------------------------+
| Retransmit | 0x03 | The receiver has encountered a problem |
| | | that requires the bundle to be |
| | | retransmitted in its entirety. |
+-------------+------+------------------------------------------+
| Not | 0x04 | Some issue with the bundle data or the |
| Acceptable | | transfer extension data was encountered. |
| | | The sender SHOULD NOT retry the same |
| | | bundle with the same extensions. |
+-------------+------+------------------------------------------+
| Extension | 0x05 | A failure processing the Transfer |
| Failure | | Extension Items has occurred. |
+-------------+------+------------------------------------------+
| Session | 0x06 | The receiving entity is in the process |
| Terminating | | of terminating the session. The sender |
| | | MAY retry the same bundle at a later |
| | | time in a different session. |
+-------------+------+------------------------------------------+
Table 6: XFER_REFUSE Reason Codes
The receiver MUST, for each transfer preceding the one to be refused, have either acknowledged all XFER_SEGMENT messages or refused the bundle transfer π¬.
The bundle transfer refusal MAY be sent before an entire data segment is received π¨. If a sender receives a XFER_REFUSE message, the sender MUST complete the transmission of any partially sent XFER_SEGMENT message. There's no way to interrupt an individual TCPCL message partway through sending it π. The sender MUST NOT subsequently commence transmission of any further segments of the refused bundle.
Note, however, that this requirement does not ensure that an entity will not receive another XFER_SEGMENT for the same bundle after transmitting a XFER_REFUSE message, since messages can cross on the wire. If this happens, subsequent segments of the bundle SHALL also be refused with a XFER_REFUSE message π.
Note: If a bundle transmission is aborted in this way, the receiver does not receive a segment with the END flag set to 1 for the aborted bundle. The beginning of the next bundle is identified by the START flag set to 1, indicating the start of a new transfer, and with a distinct Transfer ID value. π¦
5.2.5. Transfer Extension Items
Each of the Transfer Extension Items SHALL be encoded in an identical Type-Length-Value (TLV) container form, as indicated in Figure 25 π.
The fields of the Transfer Extension Item are as follows:
- Item Flags: A one-octet field containing generic bit flags related to the Item, which are listed in Table 7. All reserved header flag bits SHALL be set to 0 by the sender. All reserved header flag bits SHALL be ignored by the receiver. If a TCPCL entity receives a Transfer Extension Item with an unknown Item Type and the CRITICAL flag is 1, the entity SHALL refuse the transfer with a XFER_REFUSE reason code of "Extension Failure" π«. If the CRITICAL flag is 0, an entity SHALL skip over and ignore any item with an unknown Item Type πΈ.
- Item Type: A 16-bit unsigned integer field containing the type of the extension item. This specification creates an IANA registry for such codes (see Section 8.4) π.
- Item Length: A 16-bit unsigned integer field containing the number of Item Value octets to follow π’.
- Item Value: A variable-length data field that is interpreted according to the associated Item Type. This specification places no restrictions on an extension's use of available Item Value data π. Extension specifications SHOULD avoid the use of large data lengths, as the associated transfer cannot begin until the full extension data is sent β³.
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 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
+---------------+---------------+---------------+---------------+
| Item Flags | Item Type | Item Length...|
+---------------+---------------+---------------+---------------+
| length contd. | Item Value... |
+---------------+---------------+---------------+---------------+
Figure 25: Transfer Extension Item Format
Here are the flag bits π©:
+==========+========+==================================+
| Name | Code | Description |
+==========+========+==================================+
| CRITICAL | 0x01 | If this bit is set, it indicates |
| | | that the receiving peer must |
| | | handle the extension item. |
+----------+--------+----------------------------------+
| Reserved | others | |
+----------+--------+----------------------------------+
Table 7: Transfer Extension Item Flags
5.2.5.1. Transfer Length Extension
The purpose of the Transfer Length Extension is to let entities preemptively refuse bundles that would exceed their resources, or to prepare storage on the receiving entity for the upcoming bundle data πβ¨.
Multiple Transfer Length Extension Items SHALL NOT occur within the same transfer. The lack of a Transfer Length Extension Item in any transfer SHALL NOT imply anything regarding the potential length of the transfer π ββοΈ. The Transfer Length Extension SHALL use the IANA-assigned code point from Section 8.4.
If a transfer occupies exactly one segment (i.e., both the START flag and the END flag are 1), the Transfer Length Extension SHOULD NOT be present. The extension doesn't provide any additional information for single-segment transfers π€·ββοΈ.
The format of the Transfer Length Extension data is shown in Figure 26:
+----------------------+
| Total Length (U64) |
+----------------------+
Figure 26: Format of Transfer Length Extension Data
The Transfer Length Extension data contains the following field:
- Total Length: A 64-bit unsigned integer indicating the size of the data to be transferred. The Total Length field SHALL be treated as authoritative by the receiver. If, for whatever reason, the actual total length of bundle data received differs from the value indicated by the Total Length value, the receiver SHALL treat the transmitted data as invalid and send a XFER_REFUSE with a reason code of "Not Acceptable" π¨.
6. Session Termination β¨
This section describes the procedures for terminating a TCPCL session π. The purpose of terminating a session is to allow transfers to complete before the TCP connection is closed, but NOT to allow any new transfers to start. A session state change is necessary for this to happen, because transfers can be in progress in either direction (transfer stream) within a session. Waiting for a transfer to complete in one direction doesn't control or influence the possibility of a transfer in the other direction π¦. Either peer of a session can terminate an established session at any time π.
6.1. Session Termination Message (SESS_TERM) π
okay so if you want a clean breakup with your session πβ¨, a SESS_TERM message SHALL be sent by either entity at any point after it has finished sending any other message π. if you're the one starting the breakup, the REPLY flag of that SESS_TERM SHALL be 0 π
ββοΈ. and if a SESS_TERM shows up and you hadn't already sent one in that session, an entity SHALL send an acknowledging SESS_TERM message back π«Ά. the ack SHALL have identical data content to the one it's replying to, except the REPLY flag gets set to 1 to say "got it" π
the second a SESS_TERM is sent, the session flips to Ending π₯. while it's in the Ending state:
- an entity MAY finish an in-progress transfer in either direction.
- an entity SHALL NOT begin any new outgoing transfer for the remainder of the session.
- an entity SHALL NOT accept any new incoming transfer for the remainder of the session.
if someone tries to start a new incoming transfer while you're in Ending, the receiving entity SHALL send a XFER_REFUSE with a reason code of "Session Terminating" π
ββοΈπ
sometimes an entity is in a major rush to close a TCP connection tied to a TCPCL session πββοΈπ¨. it doesn't want to wait for transfers to finish, but it also doesn't want to force timeouts to happen. this could be because the data-link layer is about to shut down, for example β‘. instead of doing the full clean sequence, after sending a SESS_TERM, an entity MAY do an unclean termination by immediately closing the associated TCP connection πͺοΈ. when it does that, an entity SHOULD acknowledge all received XFER_SEGMENTs with a XFER_ACK before closing the TCP connection π«Ά. skipping the acks can lead to bundles or bundle fragments getting retransmitted when they didn't need to π. any delay between asking to close the TCP connection and actually closing it (the "half-closed" state) MAY be ignored by the TCPCL entity π. and if the underlying TCP connection gets closed in the middle of a transmission (in either transfer stream), the transfer SHALL be reported to the BPA as failed (check the transmission failure and reception failure indications in Section 3.1) π¨
the TCPCL itself doesn't have any required behavior for reacting to a SESS_TERM based on its reason code π€·ββοΈ. the termination just gets passed up to the BPA as an indication that the session state changed. if a termination has a reason code the BPA can't decode, the agent SHOULD treat it as having a reason code of "Unknown" π§
the format of a SESS_TERM message is shown in Figure 27 π
+-----------------------------+
| Message Header |
+-----------------------------+
| Message Flags (U8) |
+-----------------------------+
| Reason Code (U8) |
+-----------------------------+
Figure 27: Format of SESS_TERM Messages
here's the breakdown of the fields π
- Message Flags: a one-octet field of single-bit flags, read according to the descriptions in Table 8. all reserved header flag bits SHALL be set to 0 by the sender. all reserved header flag bits SHALL be ignored by the receiver.
- Reason Code: a one-octet refusal reason code, read according to the descriptions in Table 9.
+==========+========+=======================================+
| Name | Code | Description |
+==========+========+=======================================+
| REPLY | 0x01 | If this bit is set, it indicates that |
| | | this message is an acknowledgment of |
| | | an earlier SESS_TERM message. |
+----------+--------+---------------------------------------+
| Reserved | others | |
+----------+--------+---------------------------------------+
Table 8: SESS_TERM Flags
+==============+======+==========================================+
| Name | Code | Description |
+==============+======+==========================================+
| Unknown | 0x00 | A termination reason is not available. |
+--------------+------+------------------------------------------+
| Idle timeout | 0x01 | The session is being terminated due to |
| | | idleness. |
+--------------+------+------------------------------------------+
| Version | 0x02 | The entity cannot conform to the |
| mismatch | | specified TCPCL protocol version. |
+--------------+------+------------------------------------------+
| Busy | 0x03 | The entity is too busy to handle the |
| | | current session. |
+--------------+------+------------------------------------------+
| Contact | 0x04 | The entity cannot interpret or negotiate |
| Failure | | a Contact Header or SESS_INIT option. |
+--------------+------+------------------------------------------+
| Resource | 0x05 | The entity has run into some resource |
| Exhaustion | | limit and cannot continue the session. |
+--------------+------+------------------------------------------+
Table 9: SESS_TERM Reason Codes
the earliest a TCPCL session termination MAY occur is right after a Contact Header gets sent (and before any other messages) π. this can be handy as a "hey, I'm not able or willing to chat right now" signal π. BUT π¨ an entity MUST always send the Contact Header to its peer before sending a SESS_TERM message. no skipping that step, bestie!
the TCP connection MAY also be terminated before the Contact Header is received, as covered in Section 4.1 πΈ. and if receiving the Contact Header itself goes wrong (say, an invalid magic string shows up), an entity SHALL close the TCP connection without sending a SESS_TERM message π
ββοΈ.
if a session has to end before a protocol message has finished sending, the entity MUST NOT transmit the SESS_TERM message, but it still SHALL close the TCP connection π. every TCPCL message lives contiguously in the octet stream and can't get cut short or cut in line by another message π§΅. this matters most when segments are huge π₯. either the whole XFER_SEGMENT goes out before a SESS_TERM, or the connection just gets terminated mid-XFER_SEGMENT π
6.2. Idle Session Termination π
the protocol has a built-in way to cleanly end sessions that have gone quiet π΄. how long to wait before ending an idle session (if you end it at all) is totally up to the implementation and configuration π οΈ
if there's a configured time for ending idle sessions, and no TCPCL messages (other than KEEPALIVE messages) have arrived for at least that long, then either entity MAY end the session by sending a SESS_TERM with a reason code of "Idle timeout" (as shown in Table 9) πβ¨
7. Security Considerations π
this section sorts security concerns into threat categories, following the guidance in BCP 72 [RFC3552] ποΈ
7.1. Threat: Passive Leak of Node Data π
without TLS, the TCPCL shows the node ID and other configuration data to anyone snooping on the wire π±. this happens even when no transfers are happening in a session at all. you can dodge it by always using TLS, even if authentication isn't available (see Section 7.12) π
7.2. Threat: Passive Leak of Bundle Data π¦
the TCPCL can give you point-to-point transport security, but it doesn't protect data at rest and doesn't guarantee end-to-end bundle security π ββοΈ. for that, use the bundle security mechanisms defined in [RFC9172] instead π. without TLS, the TCPCL exposes all bundle data to passive eavesdroppers π. always using TLS (even without authentication) prevents this (see Section 7.12) π‘οΈ
7.3. Threat: TCPCL Version Downgrade β¬οΈ
if a TCPCL entity supports multiple protocol versions, a shady or misconfigured peer could pick an older version that doesn't support transport security π« . an on-path attacker can also tamper with a Contact Header to make it look like a lower protocol version than you wanted π€. each TCPCL entity's security policy has to make sure the negotiated version meets transport security requirements π
7.4. Threat: Transport Security Stripping π¨
if your security policy allows non-TLS sessions, the TCPCL can't protect you from active network attackers π±. an on-path attacker could set the CAN_TLS flag to 0 on either side of the Contact Header exchange, and the negotiation from Section 4.3 would then turn TLS off π. that's the "SSL Stripping" attack described in [RFC7457] π¦ΉββοΈ
the CAN_TLS flag exists so that entities without any TLS implementation can still use the TCPCL π§©. but when TLS is available on an entity, it's strongly encouraged that the security policy disallow non-TLS sessions π. this means the TLS handshake has to happen no matter what the policy-driven parameters of the handshake say, and no matter how the policy handles the outcome π€
one way to reduce the risk of TLS stripping is to use DNS-based Authentication of Named Entities (DANE) [RFC6698] toward the passive peer π. it relies on DNS and only works in one direction, so it doesn't help with applying policy toward the active peer π. it can still be useful in an environment using opportunistic security β¨. the configuration and use of DANE are outside the scope of this document π
the negotiated use of TLS works the same way as STARTTLS does in [RFC2595], [RFC4511], and others π
7.5. Threat: Weak TLS Configurations π₯
even when TLS is securing the TCPCL session, the cipher suite the TLS peers actually agree on can be weak π¬. recommendations for cipher suites are in BCP 195 [RFC7525] π. each TCPCL entity's security policy has to make sure the negotiated TLS cipher suite meets transport security requirements π
7.6. Threat: Untrusted End-Entity Certificate π
the authentication method in Section 4.4.4 uses end-entity certificates that chain back to a trusted root CA π. during a TLS handshake, either entity can send a certificate set that's missing part of the chain, possibly leaving out intermediate or root CAs π«£. in an environment where peers are known to already have the needed root and intermediate CAs, those CAs don't have to be included π§. but skipping them carries the risk that an entity doesn't actually have one of the CAs it needs ππ
7.7. Threat: Certificate Validation Vulnerabilities π₯
Okay so even when TLS is working perfectly π , an attacker can still try to exploit weak spots in certificate checking algorithms or configuration to get a secure TCPCL session using an invalid certificate π¬. A BPA treats the peer node ID within a TCPCL session as authoritative π, so if someone pulls this off, bundle data could leak and/or denial of service could hit the node ID being impersonated π.
There are so many reasons a certificate can fail to validate, and [RFC5280] and [RFC6125] both go through them π. You might be using it outside its valid time interval, using it for purposes it was never authorized for, or using it after the CA has revoked it π ββοΈ. Validating a certificate is a complex job β¨, and it can need network connectivity outside of the primary TCPCL network path(s) if the CA uses a mechanism like OCSP [RFC6960] π. How you configure and use particular certificate validation methods is outside the scope of this document π«Ά.
7.8. Threat: Symmetric Key Limits π
Even with a secure block cipher and securely established session keys, there are limits to how much plaintext can be safely encrypted with a given set of keys, as described in [AEAD-LIMITS] π. When the negotiated TLS version allows it (see [RFC8446]), it is advisable to take advantage of session key updates so you avoid those limits π¦.
7.9. Threat: BP Node Impersonation π
The certificates exchanged by TLS let you authenticate the peer DNS name and node ID πͺͺ, but it's possible that a peer doesn't provide a valid certificate, or that the certificate doesn't validate the DNS-ID/IPADDR-ID or NODE-ID of the peer (see Section 3.4) π΅βπ«. Having a CA-validated certificate doesn't alone guarantee the identity of the network host or BP node that provided it. The additional validation procedures in Section 4.4.4 bind the DNS-ID/IPADDR-ID or NODE-ID based on what's inside the certificate π§ .
DNS-ID/IPADDR-ID validation is the weaker kind of authentication, ngl π. Even if a peer is running on an authenticated network DNS name or IP address, it can still give an invalid node ID and cause bundles to be "leaked" to an invalid node. Especially in DTN environments, network names and addresses of nodes can be time-variable, so binding a certificate to a node ID gives you a more stable identity π.
NODE-ID validation makes sure the peer that a bundle is transferred to is actually the node the BPA expects it to be π―. If certificates can only be issued to DNS names, node ID validation isn't possible. In that case it could be reasonable to assume that a trusted host isn't going to present an invalid node ID π€. Deciding when DNS-ID/IPADDR-ID authentication can be trusted to validate a node ID is also a policy matter outside the scope of this document π.
One mitigation for arbitrary entities with valid PKIX certificates impersonating arbitrary node IDs is the use of the PKIX EKU key purpose id-kp-bundleSecurity (Section 4.4.2.1) π‘οΈ. When this EKU is present in the certificate, it's a stronger assertion that the private key holder should in fact be trusted to operate as a bundle node β¨.
7.10. Threat: Denial of Service π₯Ί
Everything in this section adds up to a potential denial of service to a TCPCL entity π. The denial of service could be limited to one TCPCL session, could affect other well-behaved sessions on an entity, or could affect all sessions on a host. Yikes π.
A malicious entity can trigger timeouts by constantly establishing TCPCL sessions and then delaying the sending of protocol-required data β°. The victim entity can block TCP connections from network peers that are thought to be misbehaving within the TCPCL π«.
An entity can send a huge amount of data over a TCPCL session, which means the receiving entity has to handle all of it π. The victim entity can try to stop the flood by sending a XFER_REFUSE message, or it can forcibly terminate the session π.
A "data dribble" attack is also possible πͺ±. Here an entity presents a very small Segment MRU, so transfers get split into a huge number of tiny segments, and the segmentation overhead ends up overwhelming the actual bundle data segments π₯΄. Similarly, an entity can present a very small Transfer MRU, which wastes resources on setting up and maintaining a TCPCL session that a bundle could never actually be transferred over ποΈ. The victim entity can terminate the session during parameter negotiation (Section 4.7) if the MRUs are unacceptable π .
An abusive entity could also use the keepalive mechanism to waste throughput on a network link that would otherwise be usable for bundle transmissions πΆ. Because the Keepalive Interval parameter is quantized, the smallest Session Keepalive is one second, which should be long enough to not flood the link β³. The victim entity can terminate the session during parameter negotiation (Section 4.7) if the Keepalive Interval is unacceptable π
ββοΈ.
Finally, an attacker or a misconfigured entity can cause problems at the TCP connection level that lead to unnecessary TCP retransmissions or connection resets. That effectively denies use of the TCPCL session on top of it π.
7.11. Mandatory-to-Implement TLS π
Following IETF best current practice, TLS is mandatory to implement for all TCPCL implementations, but using TLS is optional for any given TCPCL session π«§. The policy recommendations in Sections 4.2 and 4.3 both enable TLS and require TLS, but entities are allowed to disable it and not require it based on local configuration βοΈ. How you configure an entity or a session to enable or require TLS is outside the scope of this document π€·ββοΈ. Disabling TLS by configuration is different from the TLS Stripping threat described in Section 7.4 π.
7.12. Alternate Uses of TLS π·
This specification uses PKIX certificate validation and authentication within TLS πͺ. There are other uses of TLS that aren't necessarily incompatible with this spec's security goals, but they're outside the scope of this document. The following subsections give examples of those alternate TLS uses π«.
7.12.1. TLS without Authentication π«₯
In environments where PKI is available but there are restrictions on issuing certificates (including what's in the certificates), it may be possible to use TLS in a way that authenticates only the passive entity of a TCPCL session, or that doesn't authenticate either entity π΅οΈββοΈ. Using TLS in a way that doesn't successfully authenticate some claim of both peer entities of a TCPCL session is outside the scope of this document, but it does have properties similar to the opportunistic security model [RFC7435] π¦.
7.12.2. Non-certificate TLS Use ποΈ
In environments where PKI isn't available, other uses of TLS that don't need certificates are an option. Examples are pre-shared key (PSK) authentication [RFC5489] and raw public keys [RFC7250]. Those can be used to ensure confidentiality within the TCPCL π. Using non-PKI node authentication methods is outside the scope of this document π.
7.13. Predictability of Transfer IDs π²
The only requirement on Transfer IDs is that they be unique within each session, from the sending peer only π«Ά. The trivial algorithm where the first transfer starts at zero and later transfers increment by one gives absolutely predictable Transfer IDs π’. Even when a TCPCL session isn't TLS secured and an on-path attacker is causing denial of service with XFER_REFUSE messages, they can't preemptively refuse a transfer. So there's no benefit to having unpredictable Transfer IDs within a session π€·ββοΈβ¨.
8. IANA Considerations π
Registration procedures referred to in this section (e.g., the RFC Required policy) are defined in [RFC8126] π.
Some of the registries are defined as version specific for TCPCLv4, and these registries reuse some or all codepoints from TCPCLv3 π. This was done to tell apart the use of these codepoints between TCPCLv3 and TCPCLv4, while still keeping the semantics of some of the codepoints π§©.
8.1. Port Number π
Within the "Service Name and Transport Protocol Port Number Registry" [IANA-PORTS], TCP port number 4556 had previously been assigned as the default port for the TCPCL; see [RFC7242] π. That assignment doesn't change with TCPCL version 4, but the assignment reference now points to this specification π. Each TCPCL entity identifies its TCPCL protocol version in its initial contact (see Sections 3.2 and 8.2), so there's no ambiguity about which protocol is being used π‘. The related assignments for UDP and DCCP port 4556 (both registered by [RFC7122]) are unchanged πΈ.
+========================+============================+
| Parameter | Value |
+========================+============================+
| Service Name: | dtn-bundle |
+------------------------+----------------------------+
| Transport Protocol(s): | TCP |
+------------------------+----------------------------+
| Assignee: | IESG (iesg@ietf.org) |
+------------------------+----------------------------+
| Contact: | IESG (iesg@ietf.org) |
+------------------------+----------------------------+
| Description: | DTN Bundle TCP CL Protocol |
+------------------------+----------------------------+
| Reference: | This specification |
+------------------------+----------------------------+
| Port Number: | 4556 |
+------------------------+----------------------------+
Table 10: TCP Port Number for the TCPCL
8.2. Protocol Versions π§
IANA has registered the following value in the "Bundle Protocol TCP Convergence-Layer Version Numbers" registry [RFC7242] ποΈ.
+=======+=============+====================+
| Value | Description | Reference |
+=======+=============+====================+
| 4 | TCPCLv4 | This specification |
+-------+-------------+--------------------+
Table 11: New TCPCL Version Number
8.3. Session Extension Types π
okay so IANA made a brand new registry under the "Bundle Protocol" one [IANA-BUNDLE] called the "Bundle Protocol TCP Convergence-Layer Version 4 Session Extension Types" registry π and filled it with everything in Table 12. New entries go through Expert Review for the lower range 0x0001-0x7FFF. Anything in 0x8000-0xFFFF is reserved for Private or Experimental Use, and IANA doesn't record those β¨
if you're writing a new session extension type, you need to define the encoding of the Item Value data, plus any meaning or restriction on how many instances or what order of instances show up in an extension item list π§ you also need to define what the extension does when no instance of the new type is received during session negotiation π
experts are encouraged to be biased towards approving registrations unless they are abusive, frivolous, or actively harmful (not merely esthetically displeasing or architecturally dubious) π the "architecturally dubious" part is iconic, ngl π
+===============+==========================================+
| Code | Session Extension Type |
+===============+==========================================+
| 0x0000 | Reserved |
+---------------+------------------------------------------+
| 0x0001-0x7FFF | Unassigned |
+---------------+------------------------------------------+
| 0x8000-0xFFFF | Reserved for Private or Experimental Use |
+---------------+------------------------------------------+
Table 12: Session Extension Type Codes
8.4. Transfer Extension Types π¦
same energy here! IANA created the "Bundle Protocol TCP Convergence-Layer Version 4 Transfer Extension Types" registry [IANA-BUNDLE] under the "Bundle Protocol" registry and populated it with the contents of Table 13. The registration procedure is Expert Review within the lower range 0x0001-0x7FFF. Values in the range 0x8000-0xFFFF are reserved for Private or Experimental Use, which are not recorded by IANA πΈ
specs for new transfer extension types need to define the encoding of the Item Value data and any meaning or restriction on the number of or order of instances of the type within an extension item list. they also need to define how the extension functions when no instance of the new extension type is received in a transfer β¨
experts are encouraged to be biased towards approving registrations unless they are abusive, frivolous, or actively harmful (not merely esthetically displeasing or architecturally dubious) π«Ά
+===============+==========================================+
| Code | Transfer Extension Type |
+===============+==========================================+
| 0x0000 | Reserved |
+---------------+------------------------------------------+
| 0x0001 | Transfer Length Extension |
+---------------+------------------------------------------+
| 0x0002-0x7FFF | Unassigned |
+---------------+------------------------------------------+
| 0x8000-0xFFFF | Reserved for Private or Experimental Use |
+---------------+------------------------------------------+
Table 13: Transfer Extension Type Codes
8.5. Message Types π¨
the "Bundle Protocol TCP Convergence-Layer Version 4 Message Types" registry π lives under the "Bundle Protocol" registry [IANA-BUNDLE], populated with Table 14. The registration procedure is RFC Required within the lower range 0x01-0xEF. Values in the range 0xF0-0xFF are reserved for Private or Experimental Use, which are not recorded by IANA π
new message types need their message data encoding defined, plus the purpose and relationship of the new message to the existing session/transfer state within the baseline message sequencing. the use of new message types needs to be negotiated between TCPCL entities within a session (using the session extension mechanism) so the receiving entity can properly decode all message types used in the session π₯
experts are encouraged to favor new session/transfer extension types over new message types. TCPCL messages are not self-delimiting, so care must be taken when introducing new message types π
if an entity receives an unknown message type, the only thing it can do is send a MSG_REJECT and close the TCP connection. not even a clean termination is possible at that point π
+===========+==========================================+
| Code | Message Type |
+===========+==========================================+
| 0x00 | Reserved |
+-----------+------------------------------------------+
| 0x01 | XFER_SEGMENT |
+-----------+------------------------------------------+
| 0x02 | XFER_ACK |
+-----------+------------------------------------------+
| 0x03 | XFER_REFUSE |
+-----------+------------------------------------------+
| 0x04 | KEEPALIVE |
+-----------+------------------------------------------+
| 0x05 | SESS_TERM |
+-----------+------------------------------------------+
| 0x06 | MSG_REJECT |
+-----------+------------------------------------------+
| 0x07 | SESS_INIT |
+-----------+------------------------------------------+
| 0x08-0xEF | Unassigned |
+-----------+------------------------------------------+
| 0xF0-0xFF | Reserved for Private or Experimental Use |
+-----------+------------------------------------------+
Table 14: Message Type Codes
8.6. XFER_REFUSE Reason Codes π
IANA set up the "Bundle Protocol TCP Convergence-Layer Version 4 XFER_REFUSE Reason Codes" registry [IANA-BUNDLE] under the "Bundle Protocol" registry and filled it with Table 15 π the registration procedure is Specification Required within the lower range 0x00-0xEF. Values in the range 0xF0-0xFF are reserved for Private or Experimental Use, which IANA doesn't record π
new XFER_REFUSE reason codes need to define the meaning of the reason and disambiguate it from preexisting reasons. each refusal reason also needs to be usable by the receiving BPA to make retransmission or rerouting decisions π§
experts are encouraged to be biased towards approving registrations unless they are abusive, frivolous, or actively harmful (not merely esthetically displeasing or architecturally dubious) π
+===========+==========================================+
| Code | Refusal Reason |
+===========+==========================================+
| 0x00 | Unknown |
+-----------+------------------------------------------+
| 0x01 | Completed |
+-----------+------------------------------------------+
| 0x02 | No Resources |
+-----------+------------------------------------------+
| 0x03 | Retransmit |
+-----------+------------------------------------------+
| 0x04 | Not Acceptable |
+-----------+------------------------------------------+
| 0x05 | Extension Failure |
+-----------+------------------------------------------+
| 0x06 | Session Terminating |
+-----------+------------------------------------------+
| 0x07-0xEF | Unassigned |
+-----------+------------------------------------------+
| 0xF0-0xFF | Reserved for Private or Experimental Use |
+-----------+------------------------------------------+
Table 15: XFER_REFUSE Reason Codes
8.7. SESS_TERM Reason Codes πΈ
last but not least, the "Bundle Protocol TCP Convergence-Layer Version 4 SESS_TERM Reason Codes" registry [IANA-BUNDLE] sits under the "Bundle Protocol" registry and holds Table 16 π¦ the registration procedure is Specification Required within the lower range 0x00-0xEF. Values in the range 0xF0-0xFF are reserved for Private or Experimental Use, which are not recorded by IANA β¨
new SESS_TERM reason codes need to define the meaning of the reason and disambiguate it from preexisting reasons. each termination reason needs to be usable by the receiving BPA to make reconnection decisions π«Ά
experts are encouraged to be biased towards approving registrations unless they are abusive, frivolous, or actively harmful (not merely esthetically displeasing or architecturally dubious) π
+===========+==========================================+
| Code | Termination Reason |
+===========+==========================================+
| 0x00 | Unknown |
+-----------+------------------------------------------+
| 0x01 | Idle timeout |
+-----------+------------------------------------------+
| 0x02 | Version mismatch |
+-----------+------------------------------------------+
| 0x03 | Busy |
+-----------+------------------------------------------+
| 0x04 | Contact Failure |
+-----------+------------------------------------------+
| 0x05 | Resource Exhaustion |
+-----------+------------------------------------------+
| 0x06-0xEF | Unassigned |
+-----------+------------------------------------------+
| 0xF0-0xFF | Reserved for Private or Experimental Use |
+-----------+------------------------------------------+
Table 16: SESS_TERM Reason Codes
8.8. MSG_REJECT Reason Codes β¨
Okay so, under the "Bundle Protocol" registry [IANA-BUNDLE], IANA made a brand-new registry called "Bundle Protocol TCP Convergence-Layer Version 4 MSG_REJECT Reason Codes" π and filled it with the stuff in Table 17. Registration is Specification Required for the lower range 0x01-0xEF. The range 0xF0-0xFF is reserved for Private or Experimental Use, and IANA doesn't record those. π¦
If you're proposing a new MSG_REJECT reason code, your spec needs to define what the reason means and show how it's different from the reasons that already exist. Every rejection reason needs to be something the receiving TCPCL entity can actually use to make message sequencing and/or session termination decisions. π
Experts are encouraged to be biased towards approving registrations unless they are abusive, frivolous, or actively harmful (not merely esthetically displeasing or architecturally dubious). π«Ά
+===========+==========================================+
| Code | Rejection Reason |
+===========+==========================================+
| 0x00 | Reserved |
+-----------+------------------------------------------+
| 0x01 | Message Type Unknown |
+-----------+------------------------------------------+
| 0x02 | Message Unsupported |
+-----------+------------------------------------------+
| 0x03 | Message Unexpected |
+-----------+------------------------------------------+
| 0x04-0xEF | Unassigned |
+-----------+------------------------------------------+
| 0xF0-0xFF | Reserved for Private or Experimental Use |
+-----------+------------------------------------------+
Table 17: MSG_REJECT Reason Codes
8.9. Object Identifier for PKIX Module Identifier π§
IANA has registered the following in the "SMI Security for PKIX Module Identifier" registry [IANA-SMI] for identifying the module described in Appendix B.
+=========+=========================+====================+
| Decimal | Description | References |
+=========+=========================+====================+
| 103 | id-mod-dtn-tcpclv4-2021 | This specification |
+---------+-------------------------+--------------------+
Table 18: New SMI Security Module
8.10. Object Identifier for PKIX Other Name Forms πΈ
IANA has registered the following in the "SMI Security for PKIX Other Name Forms" registry [IANA-SMI] for identifying bundle endpoint IDs:
+=========+=================+====================+
| Decimal | Description | References |
+=========+=================+====================+
| 11 | id-on-bundleEID | This specification |
+---------+-----------------+--------------------+
Table 19: New PKIX Other Name Form
The formal structure of the associated Other Name Form is provided in Appendix B. The use of this OID is defined in Sections 4.4.1 and 4.4.2. π
8.11. Object Identifier for PKIX Extended Key Usage π
IANA has registered the following in the "SMI Security for PKIX Extended Key Purpose" registry [IANA-SMI] for securing BP bundles.
+=========+======================+====================+
| Decimal | Description | References |
+=========+======================+====================+
| 35 | id-kp-bundleSecurity | This specification |
+---------+----------------------+--------------------+
Table 20: New PKIX Extended Key Purpose
The formal definition of this EKU is provided in Appendix B. The use of this OID is defined in Section 4.4.2. π
9. References π
9.1. Normative References π₯
[IANA-BUNDLE] IANA, "Bundle Protocol", <https://www.iana.org/assignments/bundle/>.
[IANA-PORTS] IANA, "Service Name and Transport Protocol Port Number Registry", <https://www.iana.org/assignments/service-names-port-numbers/>.
[IANA-SMI] IANA, "Structure of Management Information (SMI) Numbers (MIB Module Registrations)", <https://www.iana.org/assignments/smi-numbers/>.
[RFC0793] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, DOI 10.17487/RFC0793, September 1981, <https://www.rfc-editor.org/info/rfc793>.
[RFC1122] Braden, R., Ed., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, DOI 10.17487/RFC1122, October 1989, <https://www.rfc-editor.org/info/rfc1122>.
[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>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>.
[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>.
[RFC6066] Eastlake 3rd, D., "Transport Layer Security (TLS) Extensions: Extension Definitions", RFC 6066, DOI 10.17487/RFC6066, January 2011, <https://www.rfc-editor.org/info/rfc6066>.
[RFC6125] Saint-Andre, P. and J. Hodges, "Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)", RFC 6125, DOI 10.17487/RFC6125, March 2011, <https://www.rfc-editor.org/info/rfc6125>.
[RFC6960] Santesson, S., Myers, M., Ankney, R., Malpani, A., Galperin, S., and C. Adams, "X.509 Internet Public Key Infrastructure Online Certificate Status Protocol - OCSP", RFC 6960, DOI 10.17487/RFC6960, June 2013, <https://www.rfc-editor.org/info/rfc6960>.
[RFC7525] Sheffer, Y., Holz, R., and P. Saint-Andre, "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May 2015, <https://www.rfc-editor.org/info/rfc7525>.
[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>.
[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>.
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.
[RFC9171] Burleigh, S., Fall, K., and E. Birrane, III, "Bundle Protocol Version 7", RFC 9171, DOI 10.17487/RFC9171, January 2022, <https://www.rfc-editor.org/info/rfc9171>.
[X.680] ITU-T, "Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation", ITU-T Recommendation X.680, ISO/IEC 8824-1:2021, February 2021, <https://www.itu.int/rec/T-REC-X.680-202102-I/en>.
9.2. Informative References π
bestie, these are the "go read this if you want the full story" sources. None of them are required reading to implement this, but they're the receipts π
[AEAD-LIMITS] Luykx, A. and K. Paterson, "Limits on Authenticated Encryption Use in TLS", August 2017, https://www.isg.rhul.ac.uk/~kp/TLS-AEbounds.pdf.
[RFC2595] Newman, C., "Using TLS with IMAP, POP3 and ACAP", RFC 2595, DOI 10.17487/RFC2595, June 1999, https://www.rfc-editor.org/info/rfc2595.
[RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC Text on Security Considerations", BCP 72, RFC 3552, DOI 10.17487/RFC3552, July 2003, https://www.rfc-editor.org/info/rfc3552.
[RFC4511] Sermersheim, J., Ed., "Lightweight Directory Access Protocol (LDAP): The Protocol", RFC 4511, DOI 10.17487/RFC4511, June 2006, https://www.rfc-editor.org/info/rfc4511.
[RFC4838] Cerf, V., Burleigh, S., Hooke, A., Torgerson, L., Durst, R., Scott, K., Fall, K., and H. Weiss, "Delay-Tolerant Networking Architecture", RFC 4838, DOI 10.17487/RFC4838, April 2007, https://www.rfc-editor.org/info/rfc4838.
[RFC5489] Badra, M. and I. Hajjeh, "ECDHE_PSK Cipher Suites for Transport Layer Security (TLS)", RFC 5489, DOI 10.17487/RFC5489, March 2009, https://www.rfc-editor.org/info/rfc5489.
[RFC5912] Hoffman, P. and J. Schaad, "New ASN.1 Modules for the Public Key Infrastructure Using X.509 (PKIX)", RFC 5912, DOI 10.17487/RFC5912, June 2010, https://www.rfc-editor.org/info/rfc5912.
[RFC6698] Hoffman, P. and J. Schlyter, "The DNS-Based Authentication of Named Entities (DANE) Transport Layer Security (TLS) Protocol: TLSA", RFC 6698, DOI 10.17487/RFC6698, August 2012, https://www.rfc-editor.org/info/rfc6698.
[RFC7122] Kruse, H., Jero, S., and S. Ostermann, "Datagram Convergence Layers for the Delay- and Disruption-Tolerant Networking (DTN) Bundle Protocol and Licklider Transmission Protocol (LTP)", RFC 7122, DOI 10.17487/RFC7122, March 2014, https://www.rfc-editor.org/info/rfc7122.
[RFC7242] Demmer, M., Ott, J., and S. Perreault, "Delay-Tolerant Networking TCP Convergence-Layer Protocol", RFC 7242, DOI 10.17487/RFC7242, June 2014, https://www.rfc-editor.org/info/rfc7242.
[RFC7250] Wouters, P., Ed., Tschofenig, H., Ed., Gilmore, J., Weiler, S., and T. Kivinen, "Using Raw Public Keys in Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", RFC 7250, DOI 10.17487/RFC7250, June 2014, https://www.rfc-editor.org/info/rfc7250.
[RFC7435] Dukhovni, V., "Opportunistic Security: Some Protection Most of the Time", RFC 7435, DOI 10.17487/RFC7435, December 2014, https://www.rfc-editor.org/info/rfc7435.
[RFC7457] Sheffer, Y., Holz, R., and P. Saint-Andre, "Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS)", RFC 7457, DOI 10.17487/RFC7457, February 2015, https://www.rfc-editor.org/info/rfc7457.
[RFC8555] Barnes, R., Hoffman-Andrews, J., McCarney, D., and J. Kasten, "Automatic Certificate Management Environment (ACME)", RFC 8555, DOI 10.17487/RFC8555, March 2019, https://www.rfc-editor.org/info/rfc8555.
[RFC9172] Birrane, III, E. and K. McKeever, "Bundle Protocol Security (BPSec)", RFC 9172, DOI 10.17487/RFC9172, January 2022, https://www.rfc-editor.org/info/rfc9172.
[DTN-BIBECT] Burleigh, S., "Bundle-in-Bundle Encapsulation", Work in Progress, Internet-Draft, draft-ietf-dtn-bibect-03, 18 February 2020, https://datatracker.ietf.org/doc/html/draft-ietf-dtn-bibect-03.
Appendix A. Significant Changes from RFC 7242 π¦
okay so this appendix is the glow-up diary πΈ it lists everything that changed from [RFC7242] and everything that got added as new messages and codes. spill the tea below!
The areas in which changes from [RFC7242] have been made to existing headers and messages are as follows:
- Split the Contact Header into pre-TLS protocol negotiation and SESS_INIT parameter negotiation. The Contact Header is now fixed length. π
- Changed the Contact Header content to limit the number of negotiated options. π
- Added a session option to negotiate maximum segment size (per each direction). β¨
- Renamed "endpoint ID" to "node ID" to conform with BPv7 terminology. π§
- Added session extension capability. π
- Added transfer extension capability. Moved the transfer total length into an extension item. π
- Defined new IANA registries for message / type / reason codes to allow renaming some codes for clarity. π
- Pointed out that segments of all new IANA registries are reserved for private/experimental use. π₯
- Expanded the Message Header to octet-aligned fields instead of bit-packing. π
- Added a bundle transfer identification number to all bundle-related messages (XFER_SEGMENT, XFER_ACK, XFER_REFUSE). π«Ά
- Added flags in XFER_ACK to mirror flags from XFER_SEGMENT. π¦
- Removed all uses of Self-Delimiting Numeric Value (SDNV) fields and replaced them with fixed-bit-length (network byte order) fields. π
- Renamed SHUTDOWN to SESS_TERM to deconflict the term "shutdown" related to TCP connections. π
- Removed the notion of a reconnection delay parameter. π
The areas in which extensions from [RFC7242] have been made as new messages and codes are as follows:
- Added the MSG_REJECT message to indicate that an unknown or unhandled message was received. π
- Added the TLS connection security mechanism. π
- Added "Not Acceptable", "Extension Failure", and "Session Terminating" XFER_REFUSE reason codes. π
- Added "Contact Failure" (contact negotiation failure) and "Resource Exhaustion" SESS_TERM reason codes. β
Appendix B. ASN.1 Module π
this is the formal ASN.1 module π€ it spells out the BundleEID structure, its Other Name Form, and the bundleSecurity EKU, written in ASN.1 syntax per [X.680]. it builds on the definitions from [RFC5912] and uses the 2002 ASN.1 notation from that document, so it's all connected, periodt β¨
<CODE BEGINS>
DTN-TCPCLv4-2021
{ iso(1) identified-organization(3) dod(6)
internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
id-mod-dtn-tcpclv4-2021(103) }
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
IMPORTS
OTHER-NAME
FROM PKIX1Implicit-2009 -- [RFC5912]
{ iso(1) identified-organization(3) dod(6) internet(1)
security(5) mechanisms(5) pkix(7) id-mod(0)
id-mod-pkix1-implicit-02(59) }
id-pkix
FROM PKIX1Explicit-2009 -- [RFC5912]
{ iso(1) identified-organization(3) dod(6) internet(1)
security(5) mechanisms(5) pkix(7) id-mod(0)
id-mod-pkix1-explicit-02(51) } ;
id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
id-on OBJECT IDENTIFIER ::= { id-pkix 8 }
DTNOtherNames OTHER-NAME ::= { on-bundleEID, ... }
-- The otherName definition for BundleEID
on-bundleEID OTHER-NAME ::= {
BundleEID IDENTIFIED BY { id-on-bundleEID }
}
id-on-bundleEID OBJECT IDENTIFIER ::= { id-on 11 }
-- Same encoding as GeneralName of uniformResourceIdentifier
BundleEID ::= IA5String
-- The Extended Key Usage key for bundle security
id-kp-bundleSecurity OBJECT IDENTIFIER ::= { id-kp 35 }
END
<CODE ENDS>
Appendix C. Example of the BundleEID Other Name Form π§
this one is a non-normative example, so it's just here to help you picture things π· it shows an otherName with a name form of BundleEID encoding the node ID "dtn://example/".
the hexadecimal form of the DER encoding of the otherName is:
a01c06082b0601050507080ba010160e64746e3a2f2f6578616d706c652f
and the text decoding in Figure 28 is the output of Peter Gutmann's "dumpasn1" program π€
0 28: [0] {
2 8: OBJECT IDENTIFIER '1 3 6 1 5 5 7 8 11'
12 16: [0] {
14 14: IA5String 'dtn://example/'
: }
: }
Figure 28: Visualized Decoding of the on-bundleEID
Acknowledgments π«Ά
this spec is based on comments about implementing [RFC7242] from Scott Burleigh, so big thank-yous to him π
the ASN.1 module and its Other Name Form are based on a recommendation from Russ Housley, who gets all the flowers πΈ
Authors' Addresses π¦
Brian Sipos
RKF Engineering Solutions, LLC
7500 Old Georgetown Road
Suite 1275
Bethesda, MD 20814-6198
United States of America
Email: brian.sipos+ietf@gmail.com
Michael Demmer
Email: demmer@gmail.com
JΓΆrg Ott
Technical University of Munich
Department of Informatics
Chair of Connected Mobility
Boltzmannstrasse 3
DE-85748 Garching
Germany
Email: ott@in.tum.de
Simon Perreault
LogMeIn
410 boulevard Charest Est
Suite 250
Quebec QC G1K 8G3
Canada
Email: simon.perreault@logmein.com
π¦ where this page comes from
- ietf: rfc9174 2022-01
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms