<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [ ]>

<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> <!-- used by XSLT processors -->

<?rfc toc="yes"?>         <!-- generate a table of contents -->
<?rfc symrefs="yes"?>     <!-- use anchors instead of numbers for references -->
<?rfc sortrefs="yes" ?>   <!-- alphabetize the references -->
<?rfc compact="yes" ?>    <!-- conserve vertical whitespace -->
<?rfc subcompact="no" ?>  <!-- but keep a blank line between list items -->

<rfc category="info" docName="draft-tbruijnzeels-sidr-validation-local-cache-02" ipr="trust200902">
  <front>
    <title>RPKI Repository Validation Using Local Cache</title>
    <author initials='T.' surname="Bruijnzeels" fullname='Tim Bruijnzeels'>
      <organization>RIPE NCC</organization>
      <address>
        <email>tim@ripe.net</email>
      </address>
    </author>
    <author fullname="Oleg Muravskiy" initials="O." surname="Muravskiy">
      <organization>RIPE NCC</organization>
      <address>
        <email>oleg@ripe.net</email>
      </address>
    </author>
    <date year="2015" />
    <area>rtg</area>
    <workgroup>SIDR</workgroup>
    <keyword>RPKI</keyword>
    <keyword>validation</keyword>
    <keyword>RRDP</keyword>
    <!-- <keyword/> -->
    <abstract>
      <t>This document describes the approach to validate the content of the RPKI repository, which is independent of
        a particular object retrieval mechanism. This allows it to be used with repositories available over rsync
        protocol (see Section 3 of<xref target="RFC6481" />), and delta protocol (
        <xref target="I-D.tbruijnzeels-sidr-delta-protocol" />), as well as repositories that use a mix of both.
      </t>
    </abstract>
  </front>
  <middle>
    <section title="Introduction">
      <t>
        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
        <xref target="RFC2119"/>.
      </t>
    </section>

    <section title="Top-down Validation of a Single Repository">

      <t>The validation of one repository is independent from any other repository, and thus, multiple repositories
        could be validated concurrently.
      </t>
      <t>The validation of a repository starts from it's Trust Anchor (TA) certificate. To retrieve the TA, the Trust
        Anchor Locator (TAL) object is used, as described in <xref target="ta-fetch" />.
      </t>
      <t>If the TA certificate is retrieved, it is validated according to the Section 2.2 of <xref target="RFC6490"/>.</t>
      <t>Then the TA certificate is validated as a resource certificate, as described in
        <xref target="ca-cert-validation" />.
      </t>
      <t>For all repository objects that were validated during this validation run, their validation timestamp is updated
        in the local store (see <xref target="store-validation-time" />).
      </t>
      <t>Outdated objects are removed from the store as described in <xref target="store-cleanup" />. This completes the
        validation of a repository.
      </t>

      <section anchor="ta-fetch" title="Fetching Trust Anchor Certificate Using Trust Anchor Locator">
        <t>The following steps are performed in order to fetch the Trust Anchor Certificate:
          <list style="symbols">
            <t>If the Trust Anchor Locator contains "prefetch.uris" field, pass the URIs contained there to the fetcher
              (see <xref target="fetch-repo" />).
            </t>
            <t>Pass to the fetcher (<xref target="fetch-object" />) the URI from the TAL (see Section 2.1 of <xref target="RFC6490" />).
            </t>
            <t>Retrieve from the local store (see <xref target="store-get-cer-by-uri" />) all certificate objects, for which
              the URI matches the URI extracted from the TAL in the previous step, and the public key matches the
              subjectPublicKeyInfo field of the TAL (Section 2.1 of <xref target="RFC6490" />).
            </t>
            <t>If no, or more than one such objects are found, issue an error and stop validation process. Otherwise,
              use that object as a Trust Anchor certificate.
            </t>
          </list>
        </t>
      </section>

      <section anchor="ca-cert-validation" title="Resource Certificate Validation">
        <t>The following steps describe the validation of a single resource certificate:
          <list style="symbols">
            <t>If both the caRepository (Section 4.8.8.1 of <xref target="RFC6487" />), and the id-ad-rpkiNotify (Section
              3.5 of <xref target="I-D.tbruijnzeels-sidr-delta-protocol" />) SIA pointers are present in the given
              resource certificate, use a local policy to determine which pointer to use. Extract the URI from the
              selected pointer and pass it to the fetcher (see <xref target="fetch-repo" />).
            </t>
            <t>For a given resource certificate, find it's manifest and certificate revocation list (CRL), using the
              procedure described in <xref target="findRecentValidMftWithCrl" />. If no such manifest and CRL could be
              found, issue an error and stop processing current certificate.
            </t>
            <t>Compare given resource certificate's manifest URI with the URI of the manifest found in the previous
              step. If they are different, issue a warning.
            </t>
            <t>Get from the local store and validate repository objects that correspond to the manifest entries, using
              the procedure described in the <xref target="mft-entries-val" />.
            </t>
            <t>Validate all resource certificate objects found on the manifest, using the CRL object found on the
              manifest, according to Section 7 of <xref target="RFC6487" />.
            </t>
            <t>Validate all ROA objects found on the manifest, using the CRL object found on the manifest, according to
              the Section 4 of <xref target="RFC6482" />.
            </t>
            <t>Validate all Ghostbusters Record objects found on the manifest, using the CRL object found on the
              manifest, according to the Section 7 of <xref target="RFC6493" />.
            </t>
            <t>For every valid resource certificate object found on the manifest, apply the procedure described in
              <xref target="ca-cert-validation">this section</xref>, recursively, provided that this resource
              certificate (identified by it's SKI) has not yet been validated during current repository validation run.
            </t>
          </list>
        </t>

        <section anchor="findRecentValidMftWithCrl" title="Finding most recent valid manifest and CRL">
          <t>Fetch from the store (see <xref target="store-get-mft-by-aki" />) all objects of type manifest, whose
            certificate's AKI field matches the SKI of the current CA certificate.
          </t>
          <t>Find the manifest object with the highest manifest number, for which all following conditions are met:
            <list style="symbols">
              <t>There is only one entry in the manifest for which the store contains exactly one object of type CRL,
                whose hash matches the hash of the entry.
              </t>
              <t>The manifest's certificate AKI equals the above CRL's AKI</t>
              <t>The above CRL is a valid object according to Section 6.3 of
                <xref target="RFC5280" />
              </t>
              <t>The manifest is a valid object according to Section 4.4 of <xref target="RFC6486" />, using the CRL
                found above
              </t>
            </list>
          </t>
          <t>Report an error for every invalid manifest with the number higher than the number of the valid manifest.
          </t>
        </section>

        <section anchor="mft-entries-val" title="Manifest entries validation">
          <t>
            For every entry in the manifest object:
            <list style="symbols">
              <t>Construct an entry's URI by appending the entry name to the current CA's publication point URI.</t>
              <t>Get all objects from the store whose hash attribute equals entry's hash (see
                <xref target="store-get-by-hash" />).
              </t>
              <t>If no such objects found, issue an error.</t>
              <t>For every found object, compare it's URI with the URI of the manifest entry. If they do not match,
                issue a warning.
              </t>
              <t>If no objects with matching URI found, issue a warning.</t>
              <t>If some objects with non-matching URI found, issue a warning.</t>
            </list>
          </t>
        </section>
      </section>

      <section title="Store Cleanup" anchor="store-cleanup">
        <t>At the end of repository validation, the store cleanup is performed. Given all objects that were validated
          during current validation run, it removes from the store (<xref target="store-delete-other" />) all objects
          whose URI attribute matches URI of validated object(s), but the hash attribute is different.
        </t>
      </section>


    </section>

    <section title="Remote Objects Fetcher" anchor="fetcher">
      <t>The fetcher is responsible for downloading objects from remote repositories. Currently rsync and RRDP
        repositories are supported.
      </t>

      <section title="Fetcher Operations">

        <section title="Fetch repository objects" anchor="fetch-repo">
          <t>This operation receives one parameter – a URI. For rsync protocol this URI points to a directory in a
            remote rsync repository. For RRDP repository it points to the repository's notification file.</t>
          <t>The fetcher performs following steps:
            <list style="symbols">
              <t>If the given URI has been downloaded recently (as specified by the local policy), do nothing.
              </t>
              <t>Download remote objects using the URI provided (for rsync repository use recursive mode).</t>
              <t>For every new object that is downloaded, try to parse it as an object of specific RPKI type
                (certificate, manifest, CRL, ROA, Ghostbusters record), based on the object's filename extension (.cer,
                .mft, .crl, .roa, and .gbr, respectively), and perform basic RPKI object validation, as specified in
                <xref target="RFC6487" /> and <xref target="RFC6488" />.
              </t>
              <t>For every downloaded valid object, record it in the local store (<xref target="store-object" />),
                and set it's last fetch time to the time it was downloaded (<xref target="store-fetch-time" />).
              </t>
            </list>
          </t>
        </section>

        <section title="Fetch single repository object" anchor="fetch-object">
          <t>This operation receives one parameter – a URI that points to an object in a remote repository.</t>
          <t>The fetcher performs following operations:
            <list style="symbols">
              <t>If the given URI has been downloaded recently (as specified by the local policy), do nothing.
              </t>
              <t>Download the remote object using the URI provided.</t>
              <t>Try to parse downloaded object as an object of a specific RPKI type (certificate,
                manifest, CRL, ROA, Ghostbusters record), based on the object's filename extension (.cer, .mft, .crl,
                .roa, and .gbr, respectively), and perform basic RPKI object validation, as specified in
                <xref target="RFC6487" /> and <xref target="RFC6488" />.
              </t>
              <t>If the downloaded object is not valid, issue an error and skip further steps.</t>
              <t>Delete objects from the local store (<xref target="store-delete-by-uri" />) using given URI.</t>
              <t>Put validated object in the local store (<xref target="store-object" />),
                and set it's last fetch time to the time it was downloaded (<xref target="store-fetch-time" />).
              </t>
            </list>
          </t>
        </section>

      </section>

    </section>

    <section title="Local Object Store" anchor="store">

      <section title="Store Operations">

        <section title="Store Repository Object" anchor="store-object">
          <t>Put given object in the store, along with it's type, URI, hash, and AKI,
            if there is no record with the same hash and URI fields.
          </t>
        </section>

        <section title="Update object's last fetch time" anchor="store-fetch-time">
          <t>For all objects in the store whose URI matches the given URI, set the last fetch time attribute to the
            given timestamp.
          </t>
        </section>

        <section title="Get objects by hash" anchor="store-get-by-hash">
          <t>Retrieve all objects from the store whose hash attribute matches the given hash.
          </t>
        </section>

        <section title="Get certificate objects by URI" anchor="store-get-cer-by-uri">
          <t>Retrieve from the store all objects of type certificate, whose URI attribute matches the given URI.
          </t>
        </section>

        <section title="Get manifest objects by AKI" anchor="store-get-mft-by-aki">
          <t>Retrieve from the store all objects of type manifest, whose AKI attribute matches the given AKI.
          </t>
        </section>

        <section title="Delete objects for URI" anchor="store-delete-by-uri">
          <t>For a given URI, delete all objects in the store with matching URI attribute.</t>
        </section>

        <section title="Delete outdated objects" anchor="store-delete-other">
          <t>For a given URI and a list of hashes, delete all objects in the store with matching URI, whose hash
            attribute is not in the given list of hashes.
          </t>
        </section>

        <section title="Update object's validation time" anchor="store-validation-time">
          <t>For all objects in the store whose hash attribute matches the given hash, set the last validation time
            attribute to the given timestamp.
          </t>
        </section>

      </section>
    </section>

    <section anchor="Acknowledgements" title="Acknowledgements">
      <t/>
    </section>
    <section anchor="IANA" title="IANA Considerations">
      <t/>
    </section>
    <section anchor="Security" title="Security Considerations">
      <t/>
    </section>
  </middle>
  <back>
    <references title="Normative References">
      <?rfc include="reference.RFC.2119.xml"?>
      <?rfc include="reference.RFC.5280.xml"?>
      <?rfc include="reference.RFC.6481.xml"?>
      <?rfc include="reference.RFC.6482.xml"?>
      <?rfc include="reference.RFC.6486.xml"?>
      <?rfc include="reference.RFC.6487.xml"?>
      <?rfc include="reference.RFC.6488.xml"?>
      <?rfc include="reference.RFC.6490.xml"?>
      <?rfc include="reference.RFC.6493.xml"?>
    </references>
    <references title="Informative References">
      <?rfc include="reference.I-D.tbruijnzeels-sidr-delta-protocol.xml"?>
    </references>
  </back>
</rfc>
