Internet-Draft Custody Receipt Block October 2026
Expires 21 April 2027 [Page]
Workgroup:
Delay/Disruption Tolerant Networking
Internet-Draft:
draft-bsvkey-dtn-custody-receipt-block-00
Published:
Intended Status:
Experimental
Expires:
Author:
Embryo Space Inc.

Signed Custody Receipts Carried in a Bundle Protocol Version 7 Extension Block

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

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.

▲

Table of Contents

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

Table 1: Custody receipt 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)
sig string Base64 Ed25519 [RFC8032] signature over the UTF-8 bytes of claimId
signerPub string Base64 DER SubjectPublicKeyInfo of the signing key [RFC8410]

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.

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

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.

10. IANA Considerations

IANA is requested to assign one value (TBD1) in the "Bundle Block Types" registry of the "Bundle Protocol" registry group:

Table 2
Value Description Reference
TBD1 Custody Receipt Block This document

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, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC9171]
Burleigh, S., Fall, K., and E. Birrane, III, "Bundle Protocol Version 7", RFC 9171, DOI 10.17487/RFC9171, , <https://www.rfc-editor.org/info/rfc9171>.
[RFC9172]
Birrane, III, E. and K. McKeever, "Bundle Protocol Security (BPSec)", RFC 9172, DOI 10.17487/RFC9172, , <https://www.rfc-editor.org/info/rfc9172>.
[RFC8949]
Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, , <https://www.rfc-editor.org/info/rfc8949>.
[RFC8259]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC8032]
Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, , <https://www.rfc-editor.org/info/rfc8032>.
[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, , <https://www.rfc-editor.org/info/rfc8410>.
[FIPS180-4]
National Institute of Standards and Technology, "Secure Hash Standard (SHS)", FIPS PUB 180-4, , <https://doi.org/10.6028/NIST.FIPS.180-4>.

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, , <https://www.rfc-editor.org/info/rfc9173>.
[RFC9052]
Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, DOI 10.17487/RFC9052, , <https://www.rfc-editor.org/info/rfc9052>.
[RFC7942]
Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, , <https://www.rfc-editor.org/info/rfc7942>.
[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, , <https://datatracker.ietf.org/doc/html/draft-ietf-dtn-bibect-05>.
[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, , <https://doi.org/10.1145/357401.357402>.

Author's Address

Embryo Space Inc.
Brownsville, TX
United States of America