RFC 8182

The RPKI Repository Delta Protocol (RRDP)

πŸ“… published July 2017, from ietf

RFC 8182: The RPKI Repository Delta Protocol (RRDP) πŸ¦‹

Okay bestie, let's do the paperwork first πŸ“‹βœ¨ This one is RFC 8182, called The RPKI Repository Delta Protocol (RRDP). The authors are T. Bruijnzeels, O. Muravskiy (RIPE NCC), B. Weber (Cobenian), and R. Austein (Dragon Research Labs). It's published as Standards Track (ISSN 2070-1721) and dated July 2017 πŸŽ€. The title block doesn't have any Obsoletes or Updates entries, so this doc doesn't list any RFCs it replaces or changes.

Abstract

Okay so in the RPKI, Certificate Authorities (CAs) publish their certificates (including end-entity certificates), Certificate Revocation Lists (CRLs), and RPKI signed objects into repositories, and Relying Parties go grab that stuff back out πŸ“¦. This doc specs a brand new RPKI Repository Delta Protocol (RRDP) for exactly that. RRDP was specifically designed for scaling πŸ“ˆπŸ’…. It leans on an Update Notification File that lists the current Snapshot and Delta Files, which you can fetch over HTTPS (HTTP over Transport Layer Security (TLS)). That means Content Distribution Networks (CDNs) or other caching setups can help serve them πŸ¦‹

Status of This Memo

Bestie, this is an Internet Standards Track document, so it's official standards-level stuff πŸ”₯

This is a product of the Internet Engineering Task Force (IETF) 🌈. 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 more on Internet Standards, check out Section 2 of RFC 7841 πŸ’œ

Info about the current status of this doc, any errata, and how to give feedback lives at http://www.rfc-editor.org/info/rfc8182 ✨

Copyright (c) 2017 IETF Trust and the persons identified as the document authors. All rights reserved πŸŽ€

This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can find at http://trustee.ietf.org/license-info, as they stand on the date this doc was published. Please read these carefully, because they spell out your rights and restrictions for this doc πŸ“œ Code Components pulled out of this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They're also provided without warranty, as described in the Simplified BSD License 🫢

Table of Contents

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
2.  Requirements Notation . . . . . . . . . . . . . . . . . . . .   4
3.  RPKI Repository Delta Protocol Implementation . . . . . . . .   4
  3.1.  Informal Overview . . . . . . . . . . . . . . . . . . . .   4
  3.2.  Certificate Authority Use . . . . . . . . . . . . . . . .   5
  3.3.  Repository Server Use . . . . . . . . . . . . . . . . . .   6
    3.3.1.  Initialization  . . . . . . . . . . . . . . . . . . .   6
    3.3.2.  Publishing Updates  . . . . . . . . . . . . . . . . .   6
  3.4.  Relying Party Use . . . . . . . . . . . . . . . . . . . .   7
    3.4.1.  Processing the Update Notification File . . . . . . .   7
    3.4.2.  Processing Delta Files  . . . . . . . . . . . . . . .   9
    3.4.3.  Processing a Snapshot File  . . . . . . . . . . . . .  10
    3.4.4.  Polling the Update Notification File  . . . . . . . .  10
    3.4.5.  Considerations Regarding Operational Failures in RRDP  11
  3.5.  File Definitions  . . . . . . . . . . . . . . . . . . . .  11
    3.5.1.  Update Notification File  . . . . . . . . . . . . . .  11
    3.5.2.  Snapshot File . . . . . . . . . . . . . . . . . . . .  13
    3.5.3.  Delta File  . . . . . . . . . . . . . . . . . . . . .  15
    3.5.4.  XML Schema  . . . . . . . . . . . . . . . . . . . . .  17
4.  Operational Considerations  . . . . . . . . . . . . . . . . .  18
  4.1.  Compatibility with previous standards . . . . . . . . . .  18
  4.2.  Distribution Considerations . . . . . . . . . . . . . . .  19
  4.3.  HTTPS Considerations  . . . . . . . . . . . . . . . . . .  19
5.  Security Considerations . . . . . . . . . . . . . . . . . . .  20
6.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  21
7.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  22
  7.1.  Normative References  . . . . . . . . . . . . . . . . . .  22
  7.2.  Informative References  . . . . . . . . . . . . . . . . .  23
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  24
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  24

1. Introduction ✨

Okay so in the RPKI, Certificate Authorities publish certificates [RFC6487], RPKI signed objects [RFC6488], manifests [RFC6486], and CRLs to repositories πŸ“š CAs might have a built-in way to publish to these repos, or they can use a separate Repository Server and publication protocol. RPKI repositories are currently reachable over the rsync protocol [RSYNC], which lets Relying Parties sync a local copy of the repository they use for validation with the remote repos [RFC6481] πŸ”

rsync [RSYNC] has been super valuable in early RPKI deployment, because operators got to gain experience without having to invent a custom protocol πŸ™Œ But real-world use has raised some concerns we want to fix here:

  • rsync [RSYNC] is designed to limit how much data has to move between client and server. However, the server needs a lot of CPU and memory for every single connection πŸ₯΅ That's a problem in the envisioned RPKI deployment, where thousands of Relying Parties query a small number of central repositories, and it makes those repos weak to denial-of-service attacks πŸ’€
  • Another concern is that there aren't supported rsync server and client libraries. In practice, every implementation has to make system calls to an rsync binary. That's inefficient, it's fragile whenever that binary gets updated, it makes it hard to catch and report problems to operators, and it complicates software development and testing 😭

This doc specs an alternative repository access protocol built on Update Notification, Snapshot, and Delta Files, which a Relying Party can fetch over HTTPS πŸ¦‹ Relying Parties can either do a full (re-)sync of their local repo copy using Snapshot Files, or use Delta Files to keep their local repo updated after the initial sync. We call this the RPKI Repository Delta Protocol, or RRDP for short πŸ’–

RRDP was designed to support scaling in RPKI's asymmetric deployment πŸ“ˆ It's consistent (in terms of data structures) with the publication protocol [RFC8181], and it treats publication events for one or more repository objects as discrete events that can be communicated to Relying Parties. This helps minimize how much data crosses the network, which helps minimize how long it takes for the repository to converge πŸƒβ€β™€οΈ RRDP also gives you a standards-based way to get consistent, point-in-time views of a single repository, so a bunch of consistency issues just disappear 🫧 Finally, these discrete events can be sent as immutable files. That means Repository Servers can pre-calculate those files only once for all clients, which limits the CPU and memory investment, and it lets a caching infrastructure take load off a Repository Server when tons of Relying Parties are querying it πŸ‘‘

This doc allows RRDP to be used as an additional repository distribution mechanism for RPKI. Over time, RRDP may replace rsync [RSYNC] as the only mandatory-to-implement repository distribution mechanism. But that transition is outside the scope of this doc 🌸

2. Requirements Notation

Okay so the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this doc get read as described in BCP 14 [RFC2119] [RFC8174], but only when they show up in all capitals, just like here 🧐

3. RPKI Repository Delta Protocol Implementation 🌈

3.1. Informal Overview

Certification Authorities in the RPKI use a Repository Server to publish their RPKI products, like manifests, CRLs, signed certificates, and RPKI-signed objects πŸ“¬ That Repository Server can be remote or embedded in the Certificate Authority engine itself. Certificates in the RPKI whose Repository Server supports RRDP include a special Subject Information Access (SIA) pointer that refers to an Update Notification File πŸŽ€

The Update Notification File has a globally unique session_id, in the form of a version 4 Universally Unique IDentifier (UUID) [RFC4122], plus a serial number. The Relying Party uses those to figure out whether it and the repository are in sync πŸ” It also includes a link to the most recent complete snapshot of current objects published by the Repository Server, and a list of links to Delta Files. There's one for each revision, starting at a point the Repository Server picks, all the way up to the repo's current revision πŸ’…

A Relying Party that learns about an Update Notification File location for the first time can download it, then download the latest Snapshot File, and boom, it has a local copy of the repository that's in sync with the Repository Server ✨ The Relying Party records the location of this Update Notification File, the session_id, and the current serial number πŸ“

Relying Parties are encouraged to re-fetch this Update Notification File at regular intervals, but not more often than once per minute ⏰ After re-fetching it, the Relying Party may find one or more Delta Files available that let it sync its local repository with the current state of the Repository Server πŸ¦‹ If there's no contiguous chain of deltas from the Relying Party's serial up to the latest repository serial, or if the session_id has changed, the Relying Party does a full resync instead 😭

As soon as the Relying Party fetches new content this way, it could start a validation process πŸ”₯ One reason a Relying Party might not do this right away is that it has learned about more than one notification location and prefers to finish all its updates before validating 🫢

The Repository Server could use a caching infrastructure to reduce its load. That's especially doable because snapshots and deltas for any given session_id and serial number contain an immutable record of the Repository Server's state at a certain point in time 🧊 For this reason, these files can be cached indefinitely. Update Notification Files, on the other hand, get polled by Relying Parties to discover whether updates exist, so they may not be cached for longer than one minute ⏳

3.2. Certificate Authority Use ✨

okay so, Certificate Authorities that use RRDP MUST put an SIA AccessDescription extension into the resource certificates they produce πŸŽ€. This is on top of the ones already defined in [RFC6487], so don't skip it πŸ’…:

             AccessDescription ::= SEQUENCE {
               accessMethod OBJECT IDENTIFIER,
               accessLocation GeneralName }

This extension MUST use an accessMethod of id-ad-rpkiNotify. Check out Section 6 for the details 🧚:

     id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
       dod(6) internet(1) security(5) mechanisms(5) pkix(7) }

     id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }

     id-ad-rpkiNotify OBJECT IDENTIFIER ::= { id-ad 13 }

The accessLocation MUST be an HTTPS URI as defined in [RFC7230]. It has to point to the Update Notification File for the Repository Server that publishes the products of this Certificate Authority certificate πŸ¦‹.


3.3. Repository Server Use 🌸

3.3.1. Initialization πŸ“

When the Repository Server starts up, it does the following things:

  • The server MUST generate a new random version 4 UUID (see Section 4.1.3 of [RFC4122]) to be used as the session_id. Main character energy πŸ‘‘.
  • The server MUST then generate a Snapshot File for serial number ONE for this new session. It has to include all currently known published objects that the Repository Server is responsible for. Ngl, this Snapshot File may contain zero publish elements at this point if no objects have been submitted for publication yet πŸ™ˆ.
  • This Snapshot File MUST be made available at a URL that is unique to this session_id and serial number, so that it can be cached indefinitely. The format and caching details for Snapshot Files get more detail in Section 3.5.2.
  • After the Snapshot File has been published, the Repository Server MUST publish a new Update Notification File. That file has to contain the new session_id, has serial number ONE, has one reference to the Snapshot File that was just published, and contains no delta references. More details on the format and caching for Update Notification Files are in Section 3.5.1 🫢.

3.3.2. Publishing Updates πŸ”₯

Whenever the Repository Server receives updates from a Certificate Authority, it MUST generate new snapshot and Delta Files within one minute. If a Repository Server services a large number of Certificate Authorities, it MAY choose to combine updates from multiple CAs. And if it does combine updates like that, it MUST make sure that publication is never postponed for longer than one minute for any of the CAs involved πŸ’–.

Here's how updates get processed:

  • The new repository serial number MUST be one greater than the current repository serial number.
  • A new Delta File MUST be generated for this new serial. This Delta File MUST include all new, replaced, and withdrawn objects for multiple CAs, if applicable, as a single change set πŸ’œ.
  • This Delta File MUST be made available at a URL that is unique to the current session_id and serial number, so that it can be cached indefinitely.
  • The format and caching concerns for Delta Files are explained in more detail in Section 3.5.3.
  • The Repository Server MUST also generate a new Snapshot File for this new serial. This file MUST contain all "publish" elements for all current objects.
  • The Snapshot File MUST be made available at a URL that is unique to this session and new serial, so that it can be cached indefinitely.
  • The format and caching concerns for Snapshot Files are explained in more detail in Section 3.5.2.
  • Any older Delta Files that, when combined with all more recent Delta Files, would make the total size of deltas exceed the size of the snapshot MUST be excluded. This keeps Relying Parties from downloading more data than necessary 🌈.
  • A new Update Notification File MUST now be created by the Repository Server. This new Update Notification File MUST include a reference to the new Snapshot File and all Delta Files selected in the previous steps.
  • The format and caching concerns for Update Notification Files are explained in more detail in Section 3.5.1.

If the Repository Server can't do all of the above for some reason, then it MUST perform a full re-initialization, as explained above in Section 3.3.1 😭.


3.4. Relying Party Use 🧚

3.4.1. Processing the Update Notification File πŸ’…

When a Relying Party performs RPKI validation and learns about a valid certificate with an SIA entry for the RRDP protocol, it SHOULD use this protocol as follows ✨.

The Relying Party MUST download the Update Notification File, unless an Update Notification File was already downloaded and processed from the same location in this validation run, or a polling strategy was used (see Section 3.4.4) πŸŽ€.

It is RECOMMENDED that the Relying Party uses a "User-Agent" header explained in Section 5.5.3. of [RFC7231] to identify the name and version of the Relying Party software it's running. This is lowkey super useful for tracking what Relying Parties can do when the RPKI standards change πŸ¦‹.

When the Relying Party downloads an Update Notification File, it MUST verify the file format and the validation steps described in Section 3.5.1.3. If that verification fails, the file MUST be rejected and RRDP cannot be used. See Section 3.4.5 for considerations πŸ™ˆ.

The Relying Party MUST verify whether the session_id matches the last known session_id for this Update Notification File location. Here's the tea πŸ«–: even though the session_id is a random UUID value, it alone MUST NOT be used by a Relying Party as a unique identifier of a session. It always has to go together with the location of the Update Notification File. The reason is that a malicious server can use an existing session_id from another Repository Server πŸ”₯.

If the session_id matches the last known session_id, then a Relying Party MAY download and process missing Delta Files as described in Section 3.4.2. This is only okay if all Delta Files for serial numbers between the last processed serial number and the current serial number in the Update Notification File can be processed this way πŸ’–.

If the session_id matches the last known session_id, but Delta Files were not used, then the Relying Party MUST download and process the Snapshot File on the Update Notification File as described in Section 3.4.3.

If the session_id does not match the last known session_id, the Relying Party MUST update its last known session_id to the value specified in the downloaded Update Notification File. After that, it MUST download and process the Snapshot File specified in the downloaded Update Notification File, as described in Section 3.4.3 πŸ‘‘.

3.4.2. Processing Delta Files 🌸

If an Update Notification File contains a contiguous chain of links to Delta Files from the last processed serial number to the current serial number, then Relying Parties MUST attempt to download and process all Delta Files in order of serial number, as follows πŸ“.

When the Relying Party downloads a Delta File, it MUST verify the file format and perform the validation steps described in Section 3.5.3.3. If that verification fails, the file MUST be rejected.

On top of that, the Relying Party MUST verify that the hash of the contents of this file matches the hash on the Update Notification File that referenced it. If the hash doesn't match, the file MUST be rejected 🫢.

If a Relying Party retrieved a Delta File that is valid according to the criteria above, it does the following:

  • The Relying Party MUST verify that the session_id matches the session_id of the Update Notification File. If the session_id values do not match, the file MUST be rejected.
  • The Relying Party MUST verify that the serial number of this Delta File is exactly one greater than the last processed serial number for this session_id. If it isn't, this file MUST be rejected.
  • The Relying Party SHOULD add all publish elements to local storage and update its last processed serial number to the serial number of this Delta File ✨.
  • When a Relying Party encounters a "withdraw" element, or a "publish" element where an object is replaced, in a delta that it retrieves from a Repository Server, it MUST verify that the object to be withdrawn or replaced was retrieved from this same Repository Server before applying the action. Failing to do so leaves the Relying Party vulnerable to malicious Repository Servers instructing it to delete or change arbitrary objects. That's a huge security risk, bestie, so please don't skip this one πŸ’€.
⚠️ Security note: if you skip the check above, a malicious Repository Server can make your Relying Party delete or change objects it has no business touching. Always confirm where a withdrawn or replaced object came from first.

If any Delta File is rejected, Relying Parties MUST process the current Snapshot File instead, as described in Section 3.4.3 πŸ”₯.

3.4.3. Processing a Snapshot File πŸŽ€

Snapshot Files MUST only be used if Delta Files are unavailable or were rejected. For a description of that process, see Section 3.4.1 πŸ¦‹.

When the Relying Party downloads a Snapshot File, it MUST verify the file format and the validation steps described in Section 3.5.2.3. If that verification fails, the file MUST be rejected.

Furthermore, the Relying Party MUST verify that the hash of the contents of this file matches the hash on the Update Notification File that referenced it. If the hash doesn't match, the file MUST be rejected 🌈.

If a Relying Party retrieved a Snapshot File that is valid according to the criteria above, it does the following:

  • The Relying Party MUST verify that the session_id matches the session_id of the Update Notification File. If the session_id values do not match, the file MUST be rejected.
  • The Relying Party MUST verify that the serial number of this Snapshot File is greater than the last processed serial number for this session_id. If this fails, the file MUST be rejected.
  • The Relying Party SHOULD then add all publish elements to local storage and update its last processed serial number to the serial number of this Snapshot File πŸ’–.

If a Snapshot File is rejected, it means RRDP cannot be used. See Section 3.4.5 for considerations 😭.

3.4.4. Polling the Update Notification File 🫢

Once a Relying Party has learned about the location, session_id, and last processed serial number of the repository that uses the RRDP protocol, it MAY start polling the Repository Server for updates. However, the Relying Party MUST NOT poll for updates more often than once every 1 minute. And to reduce data usage, Relying Parties MUST use the "If-Modified-Since" header explained in Section 3.3 of [RFC7232] in their requests πŸ“.

If a Relying Party finds that updates are available, it SHOULD download and process the file as described in Section 3.4.1 and initiate a new RPKI object validation process. A detailed description of the RPKI object validation process itself is out of scope for this document 🧚.

3.4.5. Considerations Regarding Operational Failures in RRDP πŸ’€

Okay so, if a Relying Party runs into any issues retrieving or processing any of the files in this protocol, it's going to be unable to grab new RPKI data from the affected Repository Server. 😭

Relying Parties could try alternative repository access mechanisms, if there are any, going by the accessMethod element value(s) in the SIA of the associated certificate (see Section 4.8.8 of [RFC6487]). πŸ—ΊοΈ

Relying Parties may also wish to employ re-try strategies while fetching RRDP files. They're also advised to keep old objects in their local cache so validation can still be done using those old objects. 🧠✨

It's also recommendable that re-validation and retrieval happen proactively before manifests or CRLs go stale, or certificates expire. That way, any problems on the Relying Party's side can get spotted and fixed before they turn into major drama. 🫢


3.5. File Definitions πŸ—‚οΈ

3.5.1. Update Notification File πŸ””

3.5.1.1. Purpose

The Update Notification File is how Relying Parties figure out whether anything has changed between the repository's state and their own cache. It points to the files holding the snapshot and the incremental deltas, which the Relying Party can use to get back in sync with the repository. πŸ’–

3.5.1.2. Cache Concerns

A Repository Server MAY use caching infrastructure to cache the Update Notification File and cut down on HTTPS requests. 🧊 But since Relying Parties rely on this file to check whether any updates are available, the Repository Server SHOULD make sure it isn't cached for longer than 1 minute. The one exception: it's better to serve a stale Update Notification File than no Update Notification File at all. πŸ™ˆ

How you pull this off really depends on the caching setup. Generally, a Repository Server might find certain HTTP headers handy, like Cache-Control: max-age=60 (see Section 5.2 of [RFC7234]). Another option is for the Repository Server to push new versions of the Update Notification File out to the caching infrastructure whenever that makes sense. πŸ¦‹

If the Repository Server or its distribution network is under heavy load, the Cache-Control HTTP header (or a similar mechanism) MAY be used to suggest a poll interval that's optimal for the Repository Server. However, setting it to an interval longer than 1 hour is NOT RECOMMENDED. Relying parties SHOULD line up the suggested interval with their operational practices and the expected update frequency of RPKI repository data, and they MAY discard the suggested value. 🌸

3.5.1.3. File Format and Validation

Here's an example Update Notification File:

  <notification xmlns="http://www.ripe.net/rpki/rrdp"
        version="1"
        session_id="9df4b597-af9e-4dca-bdda-719cce2c4e28"
        serial="3">
    <snapshot uri="https://host/9d-8/3/snapshot.xml" hash="AB"/>
    <delta serial="3" uri="https://host/9d-8/3/delta.xml" hash="CD"/>
    <delta serial="2" uri="https://host/9d-8/2/delta.xml" hash="EF"/>
  </notification>

Note: the URIs and hash values in this example are shortened because of formatting. πŸŽ€

These validation rules MUST be observed when creating or parsing Update Notification Files:

  • A Relying Party MUST reject any Update Notification File that is not well-formed or does not conform to the RELAX NG schema outlined in Section 3.5.4 of this document. 🚫
  • The XML namespace MUST be "http://www.ripe.net/rpki/rrdp".
  • The encoding MUST be "US-ASCII".
  • The version attribute in the notification root element MUST be "1".
  • The session_id attribute MUST be a random version 4 UUID [RFC4122], unique to this session. πŸ”‘
  • The serial attribute MUST be an unbounded, unsigned positive integer in decimal format, indicating the current version of the repository. πŸ”’
  • The Update Notification File MUST contain exactly one 'snapshot' element for the current repository version.
  • If delta elements are included, they MUST form a contiguous sequence of serial numbers starting at a revision determined by the Repository Server, up to the serial number mentioned in the notification element. Note that the elements may not be ordered. 🧩
  • The hash attribute in snapshot and delta elements MUST be the hexadecimal encoding of the SHA-256 [SHS] hash of the referenced file. The Relying Party MUST verify this hash when the file is retrieved and reject the file if the hash does not match. πŸ”

3.5.2. Snapshot File πŸ“Έ

3.5.2.1. Purpose

A snapshot is meant to capture the complete and current contents of the repository for a specific session and version. So it MUST contain all objects from the repository that are current as of the time of publication. πŸ“·

3.5.2.2. Cache Concerns

A snapshot is a picture of the repository at one specific moment in time, so it can be treated as immutable data. Snapshot Files MUST be published at a URL that is unique to the specific session and serial. πŸ”—

Because these files never change, they MAY be cached indefinitely. Still, so they don't hog a ton of space in the caching infrastructure, it is RECOMMENDED that a limited interval is used, on the order of hours or days. ⏳

To avoid race conditions, where a Relying Party downloads an Update Notification File moments before it gets updated, Repository Servers SHOULD keep old Snapshot Files around for at least 5 minutes after a new Update Notification File is published. πŸƒβ€β™€οΈπŸ’¨

3.5.2.3. File Format and Validation

Here's an example Snapshot File:

   <snapshot xmlns="http://www.ripe.net/rpki/rrdp"
          version="1"
          session_id="9df4b597-af9e-4dca-bdda-719cce2c4e28"
          serial="2">
     <publish uri="rsync://rpki.ripe.net/Alice/Bob.cer">
       ZXhhbXBsZTE=
     </publish>
     <publish uri="rsync://rpki.ripe.net/Alice/Alice.mft">
       ZXhhbXBsZTI=
     </publish>
     <publish uri="rsync://rpki.ripe.net/Alice/Alice.crl">
       ZXhhbXBsZTM=
     </publish>
   </snapshot>

These rules MUST be observed when creating or parsing Snapshot Files:

  • A Relying Party MUST reject any Snapshot File that is not well-formed or does not conform to the RELAX NG schema outlined in Section 3.5.4 of this document. 🚫
  • The XML namespace MUST be "http://www.ripe.net/rpki/rrdp".
  • The encoding MUST be "US-ASCII".
  • The version attribute in the notification root element MUST be "1".
  • The session_id attribute MUST match the expected session_id in the reference in the Update Notification File. 🎯
  • The serial attribute MUST match the expected serial in the reference in the Update Notification File. 🎯
  • Note that the publish element is similar to the publish element defined in the publication protocol [RFC8181]. However, the "tag" attribute is not used here because it is not relevant to Relying Parties. The "hash" attribute is not used here either, because this file represents a complete current state of the repository. That means it isn't relevant to know which existing RPKI object (if any) is being updated. 🧠

3.5.3. Delta File πŸ¦‹

3.5.3.1. Purpose

An incremental Delta File holds all the changes for exactly one serial increment of the Repository Server. Basically, a single delta will usually include all the new objects, updated objects, and withdrawn objects that a Certification Authority sent to the Repository Server. In its simplest form, an update could be about just one object, but it is RECOMMENDED that CAs send all changes for one of their key pairs (updated objects as well as a new manifest and CRL) as one atomic update message. πŸ’…βœ¨

3.5.3.2. Cache Concerns

Deltas reflect the difference between two consecutive versions of a repository for a given session. That's why deltas can be treated as immutable data. Delta Files MUST be published at a URL that is unique to the specific session and serial. πŸ”—

Because these files never change, they MAY be cached indefinitely. Again, to keep them from eating up space in the caching infrastructure, it is RECOMMENDED that a limited interval is used, on the order of hours or days. ⏳

To avoid race conditions, where a Relying Party downloads an Update Notification File moments before it gets updated, Repository Servers SHOULD keep old Delta Files around for at least 5 minutes after they are no longer included in the latest Update Notification File. πŸƒβ€β™€οΈπŸ’¨

3.5.3.3. File Format and Validation

Here's an example Delta File:

  <delta xmlns="http://www.ripe.net/rpki/rrdp"
         version="1"
         session_id="9df4b597-af9e-4dca-bdda-719cce2c4e28"
         serial="3">
    <publish uri="rsync://rpki.ripe.net/repo/Alice/Alice.mft"
             hash="50d8...545c">
      ZXhhbXBsZTQ=
    </publish>
    <publish uri="rsync://rpki.ripe.net/repo/Alice/Alice.crl"
             hash="5fb1...6a56">
      ZXhhbXBsZTU=
    </publish>
    <withdraw uri="rsync://rpki.ripe.net/repo/Alice/Bob.cer"
              hash="caeb...15c1"/>
  </delta>

Note that a formal RELAX NG specification of this file format is included later in this document. A Relying Party MUST NOT process any Delta File that is incomplete or not well-formed. πŸ›‘

These validation rules MUST be observed when creating or parsing Delta Files:

  • A Relying Party MUST reject any Delta File that is not well-formed or does not conform to the RELAX NG schema outlined in Section 3.5.4 of this document. 🚫
  • The XML namespace MUST be "http://www.ripe.net/rpki/rrdp".
  • The encoding MUST be "US-ASCII".
  • The version attribute in the delta root element MUST be "1".
  • The session_id attribute MUST be a random version 4 UUID unique to this session. πŸ”‘
  • The session_id attribute MUST match the expected session_id in the reference in the Update Notification File. 🎯
  • The serial attribute MUST match the expected serial in the reference in the Update Notification File. 🎯
  • Note that the publish element is similar to the publish element defined in the publication protocol [RFC8181]. However, the "tag" attribute is not used here because it is not relevant to Relying Parties. 🧠

3.5.4. XML Schema ✨

okay so this is the part where the protocol gets really precise πŸ’… it's written as a RELAX NG compact form schema for version 1 of the protocol, and the whole thing is the official blueprint for what the XML is allowed to look like πŸŽ€

#
# RELAX NG schema for the RPKI Repository Delta Protocol (RRDP).
#

default namespace = "http://www.ripe.net/rpki/rrdp"

version = xsd:positiveInteger   { maxInclusive="1" }
serial  = xsd:positiveInteger
uri     = xsd:anyURI
uuid    = xsd:string            { pattern = "[\-0-9a-fA-F]+" }
hash    = xsd:string            { pattern = "[0-9a-fA-F]+" }
base64  = xsd:base64Binary

# Notification File: lists current snapshots and deltas.

start |= element notification {
  attribute version    { version },
  attribute session_id { uuid },
  attribute serial     { serial },
  element snapshot {
    attribute uri  { uri },
    attribute hash { hash }
  },
  element delta {
    attribute serial { serial },
    attribute uri    { uri },
    attribute hash   { hash }
  }*
}

# Snapshot segment: think DNS AXFR.

start |= element snapshot {
  attribute version    { version },
  attribute session_id { uuid },
  attribute serial     { serial },
  element publish      {
    attribute uri { uri },
    base64
  }*
}

# Delta segment: think DNS IXFR.

start |= element delta {
  attribute version    { version },
  attribute session_id { uuid },
  attribute serial     { serial },
  delta_element+
}

delta_element |= element publish  {
  attribute uri  { uri },
  attribute hash { hash }?,
  base64
}

delta_element |= element withdraw {
  attribute uri  { uri },
  attribute hash { hash }
}

# Local Variables:
# indent-tabs-mode: nil
# comment-start: "# "
# comment-start-skip: "#[ \t]*"
# End:

4. Operational Considerations 🌸

4.1. Compatibility with previous standards πŸ¦‹

okay this bit is giving "let's play nice with the old crew" 🫢 the protocol was designed to replace rsync as the way an RPKI repository gets distributed, but it's also built to coexist with rsync-based implementations, so everyone can transition smoothly without drama ✨

for every repository object listed in the Snapshot and Delta Files, you get both the hash of the object's content and the rsync URI [RFC5781] of where it lives in the repository. that's what makes it possible to distribute the same RPKI repository (a set of files on a filesystem) using both rsync and RRDP, and it also lets Relying Parties tools query, combine, and validate objects coming from repositories of different types. iconic, honestly πŸ‘‘

4.2. Distribution Considerations πŸŽ€

one of the big design goals of RRDP was to minimize load on a Repository Server while it's serving clients πŸ₯Ί so the content and the URLs of the Snapshot and Delta Files don't change after they've been published in the Update Notification File. that's the secret sauce that lets you distribute them with a single HTTP server or a CDN πŸ’–

the RECOMMENDED way for Relying Parties to keep up with repository updates is to poll the Update Notification File for changes. its content gets updated with every new serial version of a repository, while its URL stays stable. to effectively distribute the Update Notification File, an "If-Modified-Since" HTTP request header is required to be present in all requests for the Update Notification File (see Section 3.4.4). so yeah, it is RECOMMENDED that Relying Party tools implement a mechanism to keep track of a previous successful fetch of an Update Notification File πŸ”₯

implementations of RRDP should also take care not to produce new versions of the repository (and therefore new Update Notification, Snapshot, and Delta Files) too often ⏰ maintenance usually includes regular updates of manifest and CRL objects on a schedule, which causes bursts of repository updates in a short window. Relying Parties are required to poll for the Update Notification File not more often than once per minute (Section 3.4.4), so generating new serial versions much more often than 1 per minute isn't practical πŸ’€ it's allowed to combine multiple updates, possibly from different CAs, into a single new serial repository version (Section 3.3.2). that shrinks the Update Notification File and the total amount of data sent to all Relying Parties, which is honestly so smart 🧚

4.3. HTTPS Considerations πŸ”’

okay bestie, listen up. a Man in the Middle (MITM) cannot produce validly signed RPKI data, BUT they can do withhold or replay attacks against a Relying Party and keep it from learning about changes in the RPKI 😭 so Relying Parties SHOULD do TLS certificate and host name validation when they fetch from an RRDP Repository Server πŸ›‘οΈ

Relying Party tools SHOULD log any TLS certificate or host name validation issues they find, so an operator can investigate the cause. BUT ngl, these validation issues are often just configuration errors or a missing common TLS trust anchor. in those cases it's actually better if the Relying Party retrieves the signed RPKI data anyway and validates that. so the Relying Party MUST continue to retrieve the data in case of errors 🫢 it MAY choose to log issues only when fetching the Update Notification File (not when it later fetches Snapshot or Delta Files from the same host), and it MAY also provide a way for operators to accept untrusted connections for a given host, once the cause has been identified 🌈

it is RECOMMENDED that Relying Parties and Repository Servers follow the Best Current Practices outlined in [RFC7525] for HTTP over TLS (HTTPS) [RFC7230]. Relying Parties SHOULD do TLS certificate and host name validation using subjectAltName dNSName identities as described in [RFC6125]. the rules and guidelines in [RFC6125] apply here, with these extra considerations:

  • Relying Parties and Repository Servers SHOULD support the DNS-ID identifier type. The DNS-ID identifier type SHOULD be present in Repository Server certificates.
  • DNS names in Repository Server certificates SHOULD NOT contain the wildcard character "*".
  • A Common Name (CN) field may be present in a Repository Server certificate's subject name but SHOULD NOT be used for authentication within the rules described in [RFC6125].
  • This protocol does not require the use of SRV-IDs.
  • This protocol does not require the use of URI-IDs.

note, though, that this validation is done on a best-effort basis and is there to highlight potential issues. RPKI object security does NOT depend on it, so Relying Parties MAY deviate from the validation steps listed above πŸ¦‹

5. Security Considerations 🚨

okay this section is SERIOUS, so read it with your whole chest 🫠 RRDP deals exclusively with transferring RPKI objects from a Repository Server to a Relying Party. the trust relationship between a Certificate Authority and its Repository Server is out of scope for this document. but from a Relying Party point of view, all RPKI objects (certificates, CRLs, and objects wrapped in Cryptographic Message Syntax (CMS)) are already covered by object security mechanisms, including signed manifests. that means these objects can be validated even though the Repository Server itself is not trusted. this document makes no change to RPKI validation procedures per se πŸ”

the original RPKI transport protocol is rsync, which offers no channel security mechanism. RRDP replaces rsync with HTTPS. the channel security under RRDP (HTTPS) is not a cure-all, but it does make some forms of denial-of-service attacks harder for an attacker πŸ’ͺ HTTPS issues are discussed in more detail in Section 4.3.

supporting both RRDP and rsync does increase the number of chances for a malicious RPKI Certificate Authority to launch denial-of-service attacks on Relying Parties, because it expands the number of URIs a Relying Party may need to contact to finish a validation run 😬 but apart from the relative cost of HTTPS versus rsync, adding RRDP doesn't really change the picture much. with either one, a malicious Certificate Authority can supply an effectively infinite series of URIs for the Relying Party to follow. the only real fix is for the Relying Party to put some kind of bound on the amount of work it's willing to do πŸ›‘ also note that the attacker in this scenario must be an RPKI Certificate Authority, because otherwise the normal RPKI object security checks would reject the malicious URIs.

processing costs for objects retrieved with RRDP can be a bit different from rsync. RRDP treats an entire set of changes as one unit (one "delta"), so it may not be practical to start processing any of the objects in the delta until the whole delta has arrived ⏳ with rsync, incremental processing may be easy, but the overall transfer cost may be higher, and there may be more corner cases where the Relying Party gets some but not all of the updated objects. overall, RRDP's behaviour is closer to a proper transactional system, which (probably) leads to an overall reliability increase ✨

RRDP is designed to scale MUCH better than rsync πŸ“ˆ in particular, it's designed to allow use of an HTTPS caching infrastructure, which reduces load on primary Repository Servers and increases resilience against denial-of-service attacks on the RPKI publication service 🏰

6. IANA Considerations πŸ“‹

IANA has updated the reference for id-ad-rpkiNotify to point to this document in the "SMI Security for PKIX Access Descriptor" registry [IANA-AD-NUMBERS] πŸŽ€

7. References πŸ“š

7.1. Normative References

Okay, bestie, these are the must-read docs the spec leans on. Every one of them is part of the actual rulebook πŸ’…πŸ“š

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <http://www.rfc-editor.org/info/rfc2119>.

[RFC4122]  Leach, P., Mealling, M., and R. Salz, "A Universally
           Unique IDentifier (UUID) URN Namespace", RFC 4122,
           DOI 10.17487/RFC4122, July 2005,
           <http://www.rfc-editor.org/info/rfc4122>.

[RFC5781]  Weiler, S., Ward, D., and R. Housley, "The rsync URI
           Scheme", RFC 5781, DOI 10.17487/RFC5781, February 2010,
           <http://www.rfc-editor.org/info/rfc5781>.

[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, <http://www.rfc-editor.org/info/rfc6125>.

[RFC6481]  Huston, G., Loomans, R., and G. Michaelson, "A Profile for
           Resource Certificate Repository Structure", RFC 6481,
           DOI 10.17487/RFC6481, February 2012,
           <http://www.rfc-editor.org/info/rfc6481>.

[RFC6487]  Huston, G., Michaelson, G., and R. Loomans, "A Profile for
           X.509 PKIX Resource Certificates", RFC 6487,
           DOI 10.17487/RFC6487, February 2012,
           <http://www.rfc-editor.org/info/rfc6487>.

[RFC7230]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
           Protocol (HTTP/1.1): Message Syntax and Routing",
           RFC 7230, DOI 10.17487/RFC7230, June 2014,
           <http://www.rfc-editor.org/info/rfc7230>.

[RFC7231]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
           Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
           DOI 10.17487/RFC7231, June 2014,
           <http://www.rfc-editor.org/info/rfc7231>.

[RFC7232]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
           Protocol (HTTP/1.1): Conditional Requests", RFC 7232,
           DOI 10.17487/RFC7232, June 2014,
           <http://www.rfc-editor.org/info/rfc7232>.

[RFC7234]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
           Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching",
           RFC 7234, DOI 10.17487/RFC7234, June 2014,
           <http://www.rfc-editor.org/info/rfc7234>.

[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, <http://www.rfc-editor.org/info/rfc7525>.

[RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
           2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
           May 2017, <http://www.rfc-editor.org/info/rfc8174>.

[RFC8181]  Weiler, S., Sonalker, A., and R. Austein, "A Publication
           Protocol for the Resource Public Key Infrastructure
           (RPKI)", DOI 10.17487/RFC8181, July 2017,
           <http://www.rfc-editor.org/info/rfc8181>.

[SHS]      National Institute of Standards and Technology, "Secure
           Hash Standard (SHS)", FIPS PUB 180-4,
           DOI 10.6028/NIST.FIPS.180-4, August 2015,
           <http://nvlpubs.nist.gov/nistpubs/FIPS/
           NIST.FIPS.180-4.pdf>.

7.2. Informative References

These ones are more like extra reading for the curious πŸ¦‹ They're not required, but they're super helpful for the full picture ✨

[IANA-AD-NUMBERS]
           IANA, "Structure of Management Information (SMI) Numbers
           (MIB Module Registrations)",
           <http://www.iana.org/assignments/smi-numbers>.

[RFC6486]  Austein, R., Huston, G., Kent, S., and M. Lepinski,
           "Manifests for the Resource Public Key Infrastructure
           (RPKI)", RFC 6486, DOI 10.17487/RFC6486, February 2012,
           <http://www.rfc-editor.org/info/rfc6486>.

[RFC6488]  Lepinski, M., Chi, A., and S. Kent, "Signed Object
           Template for the Resource Public Key Infrastructure
           (RPKI)", RFC 6488, DOI 10.17487/RFC6488, February 2012,
           <http://www.rfc-editor.org/info/rfc6488>.

[RSYNC]    "rsync", <https://rsync.samba.org>.

Acknowledgements 🫢

The authors want to thank David Mandelberg for reviewing this document. Iconic behavior, honestly πŸ‘‘

Authors' Addresses 🌸

Tim Bruijnzeels
RIPE NCC

Email: tim@ripe.net


Oleg Muravskiy
RIPE NCC

Email: oleg@ripe.net


Bryan Weber
Cobenian

Email: bryan@cobenian.com


Rob Austein
Dragon Research Labs

Email: sra@hactrn.net
πŸ“¦ where this page comes from