Network Working Group | J. Vcelak |
Internet-Draft | CZ.NIC |
Intended status: Standards Track | S. Goldberg |
Expires: September 24, 2015 | Boston University |
March 23, 2015 |
NSEC5, DNSSEC Authenticated Denial of Existence
draft-vcelak-nsec5-00
The Domain Name System Security (DNSSEC) Extensions introduced the NSEC resource record (RR) for authenticated denial of existence and the NSEC3 for hashed authenticated denial of existence. The NSEC RR allows for the entire zone contents to be enumerated if a server is queried for carefully chosen domain names; N queries suffice to enumerate a zone containing N names. The NSEC3 RR adds domain-name hashing, which makes the zone enumeration harder, but not impossible. This document introduces NSEC5, which provides an cryptographically-proven mechanism that prevents zone enumeration. NSEC5 has the additional advantage of not requiring private zone-signing keys to be present on all authoritative servers for the zone.
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 http://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 September 24, 2015.
Copyright (c) 2015 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 (http://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 Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
The DNS Security Extensions (DNSSEC) provides data integrity protection using public-key cryptography, while not requiring that authoritative servers compute signatures on-the-fly. The content of the zone is usually pre-computed and served as is. The evident advantages of this approach are reduced performance requirements per query, as well as not requiring private zone-signing keys to be present on nameservers facing the network.
With DNSSEC, each resource record (RR) set in the zone is signed. The signature is retained as an RRSIG RR directly in the zone. This enables response authentication for data existing in the zone. To ensure integrity of denying answers, an NSEC chain of all existing domain names in the zone is constructed. The chain is made of RRs, where each RR represents two consecutive domain names in canonical order present in the zone. The NSEC RRs are signed the same way as any other RRs in the zone, and each NSEC can be used to prove that a given name does not existing in a part of the domain name space.
As side-effect, however, the NSEC chain existence allows for the enumeration of the zone's contents by querying for names immediately individual RRs in the chain; N queries suffice to enumerate a zone containing N names. As such, the NSEC3 hashed denial of existence was introduced to prevent zone enumeration. In NSEC3, the original domain names in the NSEC chain are replaced by their cryptographic hashes. While NSEC3 makes zone enumeration more difficult, offline dictionary attacks are still possible and have been demonstrated; this is because hashes may be computed offline and the space of possible domain names is restricted [nsec3walker][nsec3gpu].
Zone enumeration can be prevented with NSEC3 if having the authoritative server compute NSEC3 RRs on-the-fly, in response to queries with denying responses. Usually, this is done with Minimally Covering NSEC Records or NSEC3 White Lies [RFC7129]. One of the most significant disadvantage of this approach is a required presence of the private key on all authoritative servers for the zone. This is often undesirable, as the holder of the private key can tamper with the zone content, and having private keys on many network-facing servers increases the risk that keys can be compromised.
To prevent zone content enumeration without keeping private keys on all authoritative servers, NSEC5 replaces the unkeyed cryptographic hash function used in NSEC3 with a public-key hashing scheme. Hashing in NSEC5 is performed with a separate NSEC5 key. The public portion of this key is distributed in an NSEC5KEY RR, and is used to validate NSEC5 hash values. The private portion of the NSEC5 key is present on all authoritative servers for the zone, and is used to compute hash values.
Importantly, the NSEC5KEY key cannot be used to modify the contents of the zone. Thus, any compromise of the private NSEC5 key does not lead to a compromise of zone contents; all that is lost is privacy against zone enumeration, effectively downgrading the security of NSEC5 to that of NSEC3. NSEC5 comes with a cryptographic proof of security, available in [nsec5].
The NSEC5 is not intended to replace NSEC or NSEC3. It is designed as an alternative mechanisms for authenticated denial of existence.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].
The reader is assumed to be familiar with the basic DNS and DNSSEC concepts described in [RFC1034], [RFC1035], [RFC4033], [RFC4034], [RFC4035], and subsequent RFCs that update them: [RFC2136], [RFC2181], [RFC2308], and [RFC5155].
The following terminology is used through this document:
The specification describes a protocol change that is not backward compatible with [RFC4035] and [RFC5155]. NSEC5-unaware resolver will fail to validate responses introduced by this document.
To prevent NSEC5-unaware resolvers from attempting to validate the responses, new DNSSEC algorithms identifiers are introduced, the identifiers alias with existing algorithm numbers. The zones signed according to this specification MUST use only these algorithm identifiers, thus NSEC5-unaware resolvers will treat the zone as insecure.
The new algorithm identifiers defined by this document are listed in Section 15.
To prove non-existence of a domain name in a zone, NSEC uses a chain built from domain names present in the zone. NSEC3 replaces the original domain names by their cryptographic hashes. NSEC5 is very similar to NSEC3, however a public-key based hashing scheme is used.
In NSEC5, the original domain name is hashed twice:
The NSEC5 hash determines the position of a domain name in an NSEC5 chain. That is, all the NSEC5 hashes for a zone are sorted in their canonical order, and each consecutive pair forms an NSEC5 RR.
To prove an non-existence of a particular domain name in response to a query, the server computes on the fly, the NSEC5 proof (using the private NSEC5 key). Then it uses the NSEC5 proof to compute the corresponding NSEC5 hash. It then identifies the NSEC5 RR that covers the hash. In the response message, the server returns the NSEC5 RR, it's corresponding signature (RRSIG RRset), and synthesized NSEC5PROOF RR containing the NSEC5 proof it computed on the fly.
To validate the response, the client first uses the public NSEC5 key (stored in the zone as an NSEC5KEY RR) to verify that the NSEC5 proof corresponds with the domain name to be disproved. Then, the client computes the NSEC5 hash from the NSEC5 proof and checks if the NSEC5 RR content and it's signature are valid.
The algorithms used for NSEC5 authenticated denial are independent on the algorithms used for DNSSEC signing. An NSEC5 algorithm defines how the NSEC5 proof and the NSEC5 hash is computed and validated.
The input for the NSEC5 proof computation is an RR owner name in the canonical form in the wire format and an NSEC5 private key; the output is an octet string.
The input for the NSEC5 hash computation is the corresponding NSEC5 proof; the output is an octet string.
This document defines FDH-SHA256-SHA256 NSEC5 algorithm as follows:
The NSEC5 algorithm identifier for FDH-SHA256-SHA256 is 1.
The NSEC5KEY RR stores an NSEC5 public key. The key allows clients to verify a validity of NSEC5 proof sent by a server.
The RDATA for NSEC5KEY RR is as shown below:
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Algorithm | Public Key / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Algorithm is a single octet identifying NSEC5 algorithm.
Public Key is a variable sized field holding public key material for NSEC5 proof verification.
The presentation format of the NSEC5KEY RDATA is as follows:
The Algorithm field is represented as an unsigned decimal integer.
The Public Key field is represented in Base64 encoding. Whitespace is allowed within the Base64 text.
The NSEC5 RR provides authenticated denial of existence for an RRset. One NSEC5 RR represents one piece of an NSEC5 chain, proving existence of RR types present at the original domain name and also non-existence of other domain names in a part of the hashed domain name space.
The RDATA for NSEC5 RR is as shown below:
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key Tag | Flags | Next Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Hashed Owner Name / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Type Bit Maps / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Key Tag field contains the key tag value of the NSEC5KEY RR that validates the NSEC5 RR, in network byte order. The value is computed from the NSEC5KEY RDATA using the same algorithm, which is used to compute key tag values for DNSKEY RRs. The algorithm is defined in [RFC4034].
Flags field is a single octet. The meaning of individual bits of the field is defined in Section 6.2.
Next length is an unsigned single octet specifying the length of the Next Hashed Owner Name field in octets.
Next Hashed Owner Name field is a sequence of binary octets. It contains an NSEC5 hash of the next domain name in the NSEC5 chain.
Type Bit Maps is a variable sized field encoding RR types present at the original owner name matching the NSEC5 RR. The format of the field is equivalent to the format used in NSEC3 RR, described in [RFC5155].
The following one-bit NSEC5 flags are defined:
0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ | |W|O| +-+-+-+-+-+-+-+-+
All the other flags are reserved for future use and MUST be zero.
The Opt-Out flag has the same semantics as in NSEC3. The definition and considerations in [RFC5155] are valid, except that NSEC3 is replaced by NSEC5.
The Wildcard flag indicates that a wildcard synthesis is possible at the original domain name level (i.e., there is a wildcard node immediately descending from the immediate ancestor of the original domain name). The purpose of the Wildcard flag is to reduce a maximum number of RRs required for authenticated denial of existence proof.
The presentation format of the NSEC5 RDATA is as follows:
The Key Tag field is represented as an unsigned decimal integer.
The Flags field is represented as an unsigned decimal integer.
The Next Length field is not represented.
The Next Hashed Owner Name field is represented as a sequence of case-insensitive Base32hex digits without any whitespace and without padding.
The Type Bit Maps representation is equivalent to the representation used in NSEC3 RR, described in [RFC5155].
The NSEC5PROOF record is synthesized by the authoritative server on-the-fly. The record contains the NSEC5 proof, proving a position of the owner name in an NSEC5 chain.
The RDATA for NSEC5PROOF is as as shown below:
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key Tag | Owner Name Hash / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Key Tag field contains the key tag value of the NSEC5KEY RR that validates the NSEC5PROOF RR, in network byte order.
Owner Name Hash is a variable sized sequence of binary octets encoding the NSEC5 proof of the owner name of the RR.
The presentation format of the NSEC5PROOF RDATA is as follows:
The Key Tag field is represented as an unsigned decimal integer.
The Owner Name Hash is represented in Base64 encoding. Whitespace is allowed within the Base64 text.
This section summarizes all possible types of authenticated denial of existence. For each type the following lists are included:
If NSEC5 is said to match a domain name, the owner name of the NSEC5 has to be equivalent to an NSEC5 hash of that domain name. If NSEC5 is said to cover a domain name, the NSEC5 hash of that name must lay strictly between the NSEC5 owner name and the NSEC5 Next Hashed Owner Name.
Facts to prove:
Authoritative server proofs:
Validator checks:
The processing of a No Data response for DS QTYPE differs if the Opt-Out is in effect. For DS QTYPE queries, the validator has two possible checking paths. The correct path can be simply decided by inspecting if the NSEC5 RR in the response matches the QNAME.
Note that the Opt-Out is valid only for DS QTYPE queries.
Facts to prove:
Authoritative server proofs:
Validator checks:
Facts to prove:
Authoritative server proofs:
Validator checks:
Facts to prove:
Authoritative server proofs:
Validator checks:
Facts to prove:
Authoritative server proofs:
Validator checks:
Zones using NSEC5 MUST satisfy the same properties as described in Section 7.1 of [RFC5155], with NSEC3 replaced by NSEC5. In addition, the following conditions MUST be satisfied as well:
The following steps describe one possible method to properly add required NSEC5 related records into a zone. This is not the only such existing method.
The NSEC5KEY and NSEC5 RRs MUST have the same class as the zone SOA RR. Also the NSEC5 RRs SHOULD have the same TTL value as the SOA minimum TTL field.
Notice that a use of Opt-Out is not indicated in the zone. This does not affect the ability of a server to prove insecure delegations. The Opt-Out MAY be part of the zone-signing tool configuration.
This specification modifies DNSSEC-enabled DNS responses generated by authoritative servers. In particular, it replaces use of NSEC or NSEC3 RRs in such responses with NSEC5 RRs and adds on-the-fly computed NSEC5PROOF RRs.
The authenticated denial of existence proofs in NSEC5 are almost the same as in NSEC3. However, due to introduction of Wildcard flag in NSEC5 RRs, the NSEC5 proof consists from (up to) two NSEC5 RRs, instead of (up to) three.
According to a type of a response, an authoritative server MUST include NSEC5 RRs in a response as defined in Section 8. For each NSEC5 RR in the response a matching RRSIG RRset and a synthesized NSEC5PROOF MUST be added as well.
A synthesized NSEC5PROOF RR has the owner name set to a domain name exactly matching the name required for the proof. The class and TTL of the RR MUST be the same as the class and TTL value of the corresponding NSEC5 RR. The RDATA are set according to the description in Section 7.1.
Notice, that the NSEC5PROOF owner name can be a wildcard (e.g., source of synthesis proof in wildcard No Data responses). The name also always matches the domain name required for the proof while the NSEC5 RR may only cover (not match) the name in the proof (e.g., closest encloser in Name Error responses).
If NSEC5 is used, an answering server MUST use exactly one NSEC5 chain for one signed zone.
NSEC5 MUST NOT be used in parallel with NSEC, NSEC3, or any other authenticated denial of existence mechanism that allows for enumeration of zone contents.
Similarly to NSEC3, the owner names of NSEC5 RRs are not represented in the NSEC5 chain and therefore NSEC5 records deny their own existence. The desired behavior caused by this paradox is the same as described in Section 7.2.8 of [RFC5155].
Replacement of the NSEC5 key implies generating a new NSEC5 chain. The NSEC5KEY rollover mechanism is similar to "Pre-Publish Zone Signing Key Rollover" as specified in [RFC6781]. The NSEC5KEY rollover MUST be performed as a sequence of the following steps:
The minimal delay between the steps 1. and 2. MUST be the time it takes for the data to propagate to the authoritative servers, plus the TTL value of the old NSEC5KEY RRset.
The minimal delay between the steps 2. and 3. MUST be the time it takes for the data to propagate to the authoritative servers, plus the maximum zone TTL value of any of the data in the previous version of the zone.
This document does not define mechanism to distribute NSEC5 private keys.
Zones that are signed with unknown NSEC5 algorithm or by an unavailable NSEC5 private key cannot be effectively served. Such zones SHOULD be rejected when loading and servers SHOULD respond with RCODE=2 (Server failure) when handling queries that would fall under such zones.
A zone signed using NSEC5 MAY accept dynamic updates. The changes to the zone MUST be performed in a way, that the zone satisfies the properties specified in Section 9.1 at any time.
It is RECOMMENDED that the server rejects all updates containing changes to the NSEC5 chain (or related RRSIG RRs) and performs itself any required alternations of the NSEC5 chain induced by the update.
Alternatively, the server MUST verify that all the properties are satisfied prior to performing the update atomically.
The same considerations as described in Section 9 of [RFC5155] for NSEC3 apply to NSEC5. In addition, as NSEC5 RRs can be validated only with appropriate NSEC5PROOF RRs, the NSEC5PROOF RRs MUST be all together cached and included in responses with NSEC5 RRs.
The validator MUST ignore NSEC5 RRs with Flags field values other than the ones defined in Section 6.2.
The validator MAY treat responses as bogus if the response contains NSEC5 RRs that refer to a different NSEC5KEY.
According to a type of a response, the validator MUST verify all conditions defined in Section 8. Prior to making decision based on the content of NSEC5 RRs in a response, the NSEC5 RRs MUST be validated.
To validate a denial of existence, zone NSEC5 public keys are required in addition to DNSSEC public keys. Similarly to DNSKEY RRs, the NSEC5KEY RRs are present in the zone apex.
The NSEC5 RR is validated as follows:
If the NSEC5 RR fails to validate, it MUST be ignored. If some of the conditions required for an NSEC5 proof is not satisfied, the response MUST be treated as bogus.
Notice that determining closest encloser and next closer name in NSEC5 is easier than in NSEC3. NSEC5 and NSEC5PROOF RRs are always present in pairs in responses and the original owner name of the NSEC5 RR matches the owner name of the NSEC5PROOF RR.
The same considerations as defined in Section 8.9 of [RFC5155] for NSEC3 apply to NSEC5.
A validator MUST ignore NSEC5KEY RRs with unknown NSEC5 algorithms. The practical result of this is that zones sighed with unknown algorithms will be considered bogus.
TODO: Not finished. Following information will be covered:
Quick notes on transition from NSEC/NSEC3 to NSEC5:
Quick notes on transition from NSEC5 to NSEC/NSEC3:
This document does not define format to store NSEC5 private key. Use of standardized and adopted format is RECOMMENDED.
The NSEC5 private key MAY be shared between multiple zones, however a separate key is RECOMMENDED for each zone.
The NSEC5 creates additional restrictions on domain name lengths. In particular, zones with names that, when converted into hashed owner names exceed the 255 octet length limit imposed by [RFC1035], cannot use this specification.
The actual maximum length of a domain name depends on the length of the zone name and used NSEC5 algorithm.
With FDH-SHA256-SHA256 defined in this document, the SHA-256 hash function is used to construct NSEC5 hash values. SHA-256 produces a hash of 256 bits, which can be encoded in 52 characters in Base32hex without padding. The encoded string is prepended to the name of the zone as a single label, which includes the length field of a single octet. The maximal length of the zone name is therefore 202 octets (255 - 53).
TODO: Not finished. Following information will be covered:
NSEC5 is robust to zone enumeration via offline dictionary attacks by any attacker that does not know the NSEC5 private key. Without the private NSEC5 key, that attacker cannot compute the NSEC5 proof that corresponds to a given name; the only way it can learn the NSEC5 proof value for a given name is by sending a queries for that name to the authoritative server. Without the NSEC5 proof value, the attacker cannot learn the NSEC5 hash value. Thus, even an attacker that collects the entire chain of NSEC5 RR for a zone cannot use offline attacks to "reverse" that NSEC5 hash values in these NSEC5 RR and thus learn which names are present in the zone. A formal cryptographic proof of this property is in [nsec5].
Hash collisions between QNAME and the owner name of an NSEC5 RR may occur. When they do, it will be impossible to prove the non- existence of the colliding QNAME. However, with SHA-256, this is highly unlikely (on the order of 1 in 2^128). Note that DNSSEC already relies on the presumption that a cryptographic hash function is collision resistant, since these hash functions are used for generating and validating signatures and DS RRs. See also the discussion on key lengths in [nsec5].
NSEC5 requires authoritative servers to hold the private NSEC5 key, but not the private zone-signing keys or the private key-signing keys for the zone. The private NSEC5 key needs only be as secure as the DNSSEC records whose the privacy (against zone-enumeration attacks) that NSEC5 is protecting. This is because even an adversary that knows the private NSEC5 key cannot modify the contents of the zone; this is because the zone contents are signed using the private zone-signing key, while the private NSEC5 key is only used to compute NSEC5 proof values. Thus, a compromise of the private NSEC5 keys does not lead to a compromise of the integrity of the DNSSEC record in the zone; instead, all that is lost is privacy against zone enumeration, if the attacker that knows the private NSEC5 key can compute NSEC5 hashes offline, and thus launch offline dictionary attacks. Thus, a compromise of the private NSEC5 key effectively downgrades the security of NSEC5 to that of NSEC3. A formal cryptographic proof of this property is in [nsec5].
The NSEC5 key must be long enough to withstand attacks for as long as the privacy of the zone is important. Even if the NSEC5 key is rolled frequently, its length cannot be too short, because zone privacy may be important for a period of time longer than the lifetime of the key. (For example, an attacker might collect the entire chain of NSEC5 RR for the zone over one short period, and then, later (even after the NSEC5 key expires) perform an offline dictionary attack that attempt to "reverse" the NSEC5 hash values present in the NSEC5 RRs.) This is in contrast to zone-signing and key-signing keys used in DNSSEC; these keys, which ensure the authenticity and integrity of the zone contents need to remain secure only during their lifetime.
Although the NSEC5KEY RR formats include a hash algorithm parameter, this document does not define a particular mechanism for safely transitioning from one NSEC5 algorithm to another. When specifying a new hash algorithm for use with NSEC5, a transition mechanism MUST also be defined. It is possible that the only practical and palatable transition mechanisms may require an intermediate transition to an insecure state, or to a state that uses NSEC or NSEC3 records instead of NSEC5.
This document updates the IANA registry "Domain Name System (DNS) Parameters" in subregistry "Resource Record (RR) TYPEs", by defining the following new RR types:
This document creates a new IANA registry for NSEC5 algorithms. This registry is named "DNSSEC NSEC5 Algorithms". The initial content of the registry is:
This document updates the IANA registry "DNS Security Algorithm Numbers" by defining following aliases:
This document would not be possible without help of Moni Naor (Weizmann Institute), Dimitrios Papadopoulos (Boston University), Sachin Vasant (Cisco Systems), Leonid Reyzin (Boston University), and Asaf Ziv (Weizmann Institute) who contributed to the design of NSEC5, and Ondrej Sury (CZ.NIC Labs) who provided advice on its implementation.
[nsec5] | Goldberg, S., Naor, M., Papadopoulos, D., Reyzin, L., Vasant, S. and A. Ziv, "NSEC5: Provably Preventing DNSSEC Zone Enumeration", July 2014. |
[nsec3gpu] | Wander, M., Schwittmann, L., Boelmann, C. and T. Weis, "GPU-Based NSEC3 Hash Breaking", in IEEE Symp. Network Computing and Applications (NCA), 2014. |
[nsec3walker] | Bernstein, D., "Nsec3 walker", 2011. |
[RFC6781] | Kolkman, O., Mekking, W. and R. Gieben, "DNSSEC Operational Practices, Version 2", RFC 6781, December 2012. |
[RFC7129] | Gieben, R. and W. Mekking, "Authenticated Denial of Existence in the DNS", RFC 7129, February 2014. |
The Full Domain Hash (FDH) is a RSA-based scheme that allows authentication of hashes using public-key cryptography.
In this document, the notation from [RFC3447] is used.
Used parameters:
Fixed options:
Used primitives:
FDH_SIGN(K, M)
Input:
Output:
Steps:
FDH_VERIFY((n, e), M, S)
Input:
Output:
Steps:
Note to RFC Editor: if this document does not obsolete an existing RFC, please remove this appendix before publication as an RFC.
Note to RFC Editor: please remove this appendix before publication as an RFC.