Delay/Disruption Tolerant Networking Embryo Space Inc. Internet-Draft 18 October 2026 Intended status: Experimental Expires: 21 April 2027 Signed Custody Receipts Carried in a Bundle Protocol Version 7 Extension Block draft-bsvkey-dtn-custody-receipt-block-00 Abstract This document defines the Custody Receipt Block, a Bundle Protocol Version 7 (BPv7) extension block that carries a chain of signed custody receipts inside the bundle those receipts describe. Each node that chooses to act as a custodian appends one receipt stating that it held the bundle, which node it received it from, and when it received and forwarded it. Nodes that do not implement the block forward it unchanged and are never required to read the payload or to sign anything. A verifier holding the custodians' public keys can check the chain after the fact and can report, rather than infer, any part of the route for which no receipt exists. The receipts are evidence for accounting and dispute resolution between operators. They are not Bundle Protocol administrative records and they do not replace or modify custody transfer signalling. About This Document This note is to be removed before publishing as an RFC. An open reference implementation (Apache-2.0), test vectors and live interoperability results are at https://github.com/BSVKey/dtn- custody-demo. The implementation uses block type 224 from the private and experimental range pending any assignment. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Expires 21 April 2027 [Page 1] Internet-Draft Custody Receipt Block October 2026 Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 21 April 2027. Copyright Notice Copyright (c) 2026 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 . . . . . . . . . . . . . . . . . . . . . . . . 3 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 3. Custody Receipt Format . . . . . . . . . . . . . . . . . . . 4 3.1. Canonical Encoding . . . . . . . . . . . . . . . . . . . 4 3.2. Members . . . . . . . . . . . . . . . . . . . . . . . . . 4 3.3. Subject Identifiers . . . . . . . . . . . . . . . . . . . 5 4. The Custody Receipt Block . . . . . . . . . . . . . . . . . . 5 4.1. Block Format . . . . . . . . . . . . . . . . . . . . . . 5 4.2. Block Processing Control Flags . . . . . . . . . . . . . 6 5. Processing . . . . . . . . . . . . . . . . . . . . . . . . . 6 5.1. Custodian Behavior . . . . . . . . . . . . . . . . . . . 6 5.2. Forwarder Behavior . . . . . . . . . . . . . . . . . . . 6 5.3. Verification . . . . . . . . . . . . . . . . . . . . . . 6 6. Interaction with BPSec . . . . . . . . . . . . . . . . . . . 7 7. Implementation Status . . . . . . . . . . . . . . . . . . . . 7 8. Open Issues . . . . . . . . . . . . . . . . . . . . . . . . . 7 9. Security Considerations . . . . . . . . . . . . . . . . . . . 8 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 9 11.1. Normative References . . . . . . . . . . . . . . . . . . 9 11.2. Informative References . . . . . . . . . . . . . . . . . 10 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 10 Expires 21 April 2027 [Page 2] Internet-Draft Custody Receipt Block October 2026 1. Introduction In a delay/disruption tolerant network, a bundle may be held for minutes to hours by nodes run by different operators before it reaches its destination. When something goes wrong (a bundle arrives late, is lost, or arrives altered), each operator holds only its own local logs. Those logs are not portable evidence: another party cannot verify them without trusting the operator that wrote them. BPv7 [RFC9171] does not include custody transfer; reliable hop-by-hop transfer is addressed separately [I-D.ietf-dtn-bibect]. Custody transfer answers "who is responsible for retransmission now". This document addresses a different question: "who can prove they held this bundle, and when". The mechanism is a signed receipt that travels with the bundle and can be verified by any party, at any later time, without contacting the nodes that produced it. The design follows the end-to-end argument [SRC84]: forwarding nodes do nothing beyond normal BPv7 block processing. Only nodes whose operators choose to act as custodians produce receipts, and after the first custodian none of them need to parse the payload. A verifier at the destination, or any later auditor, does the checking. This document is published as Experimental so that the format can be evaluated in multi-operator deployments. It reflects version 1 of an implementation that has been run through four independent BPv7 implementations; see Section 7. 2. Terminology The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. Custodian: A node whose operator has chosen to sign receipts for bundles it holds. Being a custodian in this sense is independent of custody transfer and implies no retransmission responsibility. Forwarder: Any BPv7 node that is not acting as a custodian for a given bundle. A forwarder may or may not implement this specification. Origin: The first custodian for a bundle. It establishes the subject identifiers that later receipts repeat. Custody receipt (receipt): A signed statement by one custodian that Expires 21 April 2027 [Page 3] Internet-Draft Custody Receipt Block October 2026 it held one bundle, defined in Section 3. A receipt is not a BPv7 administrative record (Section 6.1 of [RFC9171]). Receipt chain: The ordered list of receipts carried in one Custody Receipt Block. Uncustodied transit gap (gap): A part of the route, visible to a verifier, for which no receipt exists. 3. Custody Receipt Format 3.1. Canonical Encoding Version 1 receipts are JSON objects [RFC8259]. The canonical form of a receipt is its JSON serialization with the keys of every object sorted recursively by UTF-16 code unit, no insignificant whitespace, and standard JSON string escaping. Implementations MUST reject nesting deeper than 32 levels. The content identifier of a receipt is the string "0x" followed by the lowercase hexadecimal SHA-256 [FIPS180-4] digest of the UTF-8 canonical form of the receipt with the members "claimId", "sig" and "signerPub" removed. 3.2. Members +=============+=========+==========================================+ | Member | Type | Meaning | +=============+=========+==========================================+ | kind | string | "custody/1" | +-------------+---------+------------------------------------------+ | payloadId | string | Identifier of the application data unit | | | | the bundle belongs to, set by the origin | +-------------+---------+------------------------------------------+ | bundleId | string | Subject identifier for this bundle, set | | | | by the origin (Section 3.3) | +-------------+---------+------------------------------------------+ | prevHop | string | EID of the node this custodian received | | | | the bundle from | +-------------+---------+------------------------------------------+ | thisHop | string | EID of this custodian | +-------------+---------+------------------------------------------+ | receivedAt | integer | Reception time, milliseconds since | | | | 1970-01-01T00:00:00Z | +-------------+---------+------------------------------------------+ | forwardedAt | integer | Forwarding time, same unit | +-------------+---------+------------------------------------------+ | claimId | string | The content identifier (Section 3.1) | Expires 21 April 2027 [Page 4] Internet-Draft Custody Receipt Block October 2026 +-------------+---------+------------------------------------------+ | sig | string | Base64 Ed25519 [RFC8032] signature over | | | | the UTF-8 bytes of claimId | +-------------+---------+------------------------------------------+ | signerPub | string | Base64 DER SubjectPublicKeyInfo of the | | | | signing key [RFC8410] | +-------------+---------+------------------------------------------+ Table 1: Custody receipt members The member names are those of the deployed version 1 format and are retained unchanged so that existing receipts remain verifiable. A custodian SHOULD take prevHop from the Previous Node block (Section 4.4.1 of [RFC9171]) when one is present. An encoded receipt is about 530 octets. 3.3. Subject Identifiers The origin sets payloadId and bundleId. Every later custodian MUST copy both values from the first receipt in the block and MUST NOT need to parse the payload to do so. This is what allows a custodian to treat the application data unit as opaque, including when the payload is encrypted with a Block Confidentiality Block [RFC9172]. A false subject identifier cannot pass verification, because the verifier derives the expected bundleId from the payload it receives (Section 5.3). The derivation is application specific. The reference implementation carries a payload split into chunks under a Merkle root and uses the content identifier of {payloadId, index, leafHex} for the chunk carried by the bundle. 4. The Custody Receipt Block 4.1. Block Format The block-type code is TBD1 (Section 10). Implementations of this version use 224, from the private and experimental range, until a code point is assigned. The block-type-specific data is a CBOR [RFC8949] array of text strings. Each text string is the canonical form of one signed receipt, in the order the receipts were appended. Carrying the canonical form as an opaque string means signatures verify over the exact octets carried, with no re-serialization. custody-receipt-block-data = [ + tstr ] ; canonical JSON receipts A bundle MUST NOT contain more than one Custody Receipt Block. Expires 21 April 2027 [Page 5] Internet-Draft Custody Receipt Block October 2026 4.2. Block Processing Control Flags The block MUST have "Block must be replicated in every fragment" set, and MUST have "Delete bundle if block can't be processed" and "Discard block if it can't be processed" clear. A node that does not implement this specification therefore retains the block and forwards it unchanged (Section 4.2.4 of [RFC9171]). A CRC-32C is RECOMMENDED. 5. Processing 5.1. Custodian Behavior A custodian that holds a bundle and chooses to sign for it: 1. If no Custody Receipt Block is present, acts as the origin: determines payloadId and bundleId and adds the block. 2. Otherwise copies payloadId and bundleId from the first receipt. 3. Appends its own signed receipt to the array and recomputes the block CRC. It MUST NOT alter or reorder earlier receipts. Which bundles a node signs for is local policy (for example, by source, destination, service agreement or the presence of the block). No new naming scheme is needed. 5.2. Forwarder Behavior A forwarder performs normal BPv7 processing. It does not read the payload, does not sign, and need not implement this specification. 5.3. Verification A verifier MUST derive bundleId from the payload it received, never from the receipts. It then checks every receipt: the content identifier MUST equal claimId; the signature MUST verify under signerPub; bundleId MUST equal the derived value; and signerPub MUST equal a key the verifier obtained independently for the EID in thisHop. A receipt that fails any of these checks is a verification failure. Two modes are defined: Pinned route: The verifier knows the expected ordered list of custodians. The number of receipts MUST equal the length of the list, each thisHop MUST match its position, and each prevHop after the first MUST equal the previous receipt's thisHop. Expires 21 April 2027 [Page 6] Internet-Draft Custody Receipt Block October 2026 Audit: The verifier knows the custodians' keys but not the route. Wherever a receipt's prevHop differs from the previous receipt's thisHop (or from the expected origin), and wherever the node that delivered the bundle (from its Previous Node block) differs from the last receipt's thisHop, the verifier MUST report a gap naming the last signed hop, the next signed hop, and the unsigned node observed. A result with any gap MUST NOT be reported as complete. A missing receipt is reported as missing and is never inferred. A receipt that is present but invalid is a failure, not a gap. 6. Interaction with BPSec Because every custodian modifies the Custody Receipt Block, a Block Integrity Block [RFC9172] MUST NOT target it. Receipts carry their own signatures. A BIB that targets the payload or the primary block is unaffected by appending receipts, since appending changes neither. A Block Confidentiality Block MUST NOT target the Custody Receipt Block, because later custodians must read the first receipt. 7. Implementation Status Note to the RFC Editor: please remove this section before publication, as described in [RFC7942]. One implementation exists: dtn-custody-demo, Embryo Space Inc., Apache-2.0, JavaScript (Node.js) with no third-party dependencies, https://github.com/BSVKey/dtn-custody-demo. It includes its own BPv7 codec, which was checked byte for byte against the uD3TN project's Python library. In live runs the block was carried byte-identical across a scheduled contact gap by uD3TN, NASA HDTN, JPL ION and Aalyria Hardy, none of which implement it. The BIB-HMAC-SHA2 code [RFC9173] reproduces the RFC 9173 Appendix A vectors byte for byte. A payload BIB was carried through the same four implementations and verified before and after custodians appended receipts. Results and commands are in the repository (transport/bpv7/RESULTS.md). Testing against JPL ION as a BIB acceptor and signer found that ION builds the integrity-protected plaintext for a payload target from the whole serialized block rather than from the block-type-specific data as a byte string (Section 3.7 of [RFC9173]), and omits the SHA variant parameter while signing with HMAC 256/256. The reference implementation interoperates with ION through an optional mode and uses the RFC 9173 construction by default. This is noted because the two constructions cannot verify each other's BIBs. 8. Open Issues Expires 21 April 2027 [Page 7] Internet-Draft Custody Receipt Block October 2026 * Encoding. A CBOR receipt signed with COSE_Sign1 [RFC9052] would fit BPv7 better than canonical JSON and would be much smaller. Version 1 keeps JSON for compatibility with receipts already produced. * Subject identifier. Binding receipts to the BPv7 bundle identity (source EID, creation timestamp and, for fragments, offset) in addition to an application identifier would let verifiers without application knowledge check the binding. * Fragmentation. Receipts describe the whole bundle. Behavior for a custodian that holds only some fragments is not yet defined. * Growth. The block grows by one receipt per custodian. Batching receipts per contact under a Merkle root, as the reference implementation does outside the block, may be preferable on long routes. 9. Security Considerations Key distribution. Receipts are only as meaningful as the binding between a custodian EID and its key. Verifiers MUST obtain keys independently of the receipts and MUST NOT trust signerPub on its own. Stripping. Any forwarder can remove the block or truncate the array and recompute the CRC. This cannot be prevented by the block itself; it is detected because the removed custodians appear as gaps. A verifier MUST treat a gap as absence of evidence, not as evidence of absence. Replay. A receipt copied to another bundle fails verification because bundleId is derived from the received payload. False times. A custodian can sign false receivedAt and forwardedAt values. Receipts bind a custodian to its claims; they do not prove the claims are true. Inconsistent times across adjacent receipts can be flagged by the verifier. Denial of service. Verification cost and block size grow linearly with the number of receipts. A verifier SHOULD bound the number of receipts it will process. Privacy. Receipts reveal the custodians on a route and their timing to anyone who can read the bundle. Expires 21 April 2027 [Page 8] Internet-Draft Custody Receipt Block October 2026 10. IANA Considerations IANA is requested to assign one value (TBD1) in the "Bundle Block Types" registry of the "Bundle Protocol" registry group: +=======+=======================+===============+ | Value | Description | Reference | +=======+=======================+===============+ | TBD1 | Custody Receipt Block | This document | +-------+-----------------------+---------------+ Table 2 11. References 11.1. Normative References [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC9171] Burleigh, S., Fall, K., and E. Birrane, III, "Bundle Protocol Version 7", RFC 9171, DOI 10.17487/RFC9171, January 2022, . [RFC9172] Birrane, III, E. and K. McKeever, "Bundle Protocol Security (BPSec)", RFC 9172, DOI 10.17487/RFC9172, January 2022, . [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, . [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, . [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, January 2017, . Expires 21 April 2027 [Page 9] Internet-Draft Custody Receipt Block October 2026 [RFC8410] Josefsson, S. and J. Schaad, "Algorithm Identifiers for Ed25519, Ed448, X25519, and X448 for Use in the Internet X.509 Public Key Infrastructure", RFC 8410, DOI 10.17487/RFC8410, August 2018, . [FIPS180-4] National Institute of Standards and Technology, "Secure Hash Standard (SHS)", FIPS PUB 180-4, August 2015, . 11.2. Informative References [RFC9173] Birrane, III, E., White, A., and S. Heiner, "Default Security Contexts for Bundle Protocol Security (BPSec)", RFC 9173, DOI 10.17487/RFC9173, January 2022, . [RFC9052] Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, DOI 10.17487/RFC9052, August 2022, . [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, July 2016, . [I-D.ietf-dtn-bibect] Burleigh, S., Montilla, A., Deaton, J., and C. Caini, "Bundle-in-Bundle Encapsulation", Work in Progress, Internet-Draft, draft-ietf-dtn-bibect-05, 15 March 2025, . [SRC84] Saltzer, J. H., Reed, D. P., and D. D. Clark, "End-to-End Arguments in System Design", ACM Transactions on Computer Systems 2(4), 277-288, November 1984, . Author's Address Embryo Space Inc. Brownsville, TX United States of America Email: embryospace@gmail.com Expires 21 April 2027 [Page 10]