;;; -*- Lisp -*- ;;; $Id$ ;;; Copyright (C) 2007--2008 American Registry for Internet Numbers ("ARIN") ;;; ;;; Permission to use, copy, modify, and distribute this software for any ;;; purpose with or without fee is hereby granted, provided that the above ;;; copyright notice and this permission notice appear in all copies. ;;; ;;; THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH ;;; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ;;; AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT, ;;; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ;;; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ;;; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ;;; PERFORMANCE OF THIS SOFTWARE. ;;; Scratch pad for working out API design for RPKI engine. ;;; ;;; This file is psuedocode, I just wanted to take advantage of ;;; emacs's built-in support for languages with reasonable syntax. ;;; ;;; Terminology: ;;; ;;; - IRBE: Internet Registry Back End ;;; ;;; - RE: RPKI Engine ;;; Repository update protocol. Same basic CMS-signed XML mess we use ;;; elsewhere, this time with RE as client, lodging repository as ;;; server. Authorization is a combination of business key and ;;; resource key/cert: biz key demonstrates that we're authorized to ;;; play with this repository at all, resource cert demonstrates ;;; relationship to the datum to be published. ;;; This would be a trivial protocol, except for two constraints: ;;; ;;; a) In the case where parent and child are sharing a repository, ;;; we'd like to nest child under parent to speed up rcynic. ;;; ;;; b) The repository operator might want to do some checks to assure ;;; itself that what it's about to allow the RE to publish is not ;;; dangerous toxic waste. ;;; ;;; Protocol goals as of last discussion in Prague: ;;; ;;; 1) "Negotiate" publication point URI. This is a bit complex, in ;;; that part of the URI may come from the publication ;;; repository, parts from the RE's parent, and parts from the RE ;;; itself. Some discussion over whether we need online protocol ;;; to negotiate the publication repository's part, no firm ;;; consensus, plurality of the room was leaning towards "no", ;;; ie, the repository's portion of the URI is negotiated via the ;;; business channel and configured into the RE by the IRBE. ;;; ;;; 2) In case where parent and child are in fact sharing repository, ;;; repository operator is responsible for keeping these two users' ;;; naming schemes from coliding with each other. More precisely, ;;; the repository operator is responsible for checking to see that ;;; the parent agreed to let the child publish in a particular ;;; subtree. Fortunately, this is an easy check: the parent has to ;;; issue a cert to the child anyway, and that cert will contain a ;;; signature by the parent over the child's SIA URI, so the ;;; repository just has to check that. For purposes of this check, ;;; the parent's cert (which the repository has, by definition, ;;; since this is the nested hosting case) can serve as a trust ;;; anchor for checking the child's SIA. ;;; ;;; 3) To the extent that the repository operator wants to guard ;;; against toxic waste, it might want to check further up the ;;; resource cert chain, regardless of where the ancestors lodge. ;;; For this to work properly, the repository operator needs to ;;; agree (as part of a business negotiation, probably) with the RE ;;; on which trust anchors the repository should use to perform ;;; these checks; ultimately, this decision (as with any TA choice) ;;; is up to the relying party (in this case the repository ;;; operator), but if there's going to be a problem due to ;;; mismatched TA choices, we would really like to throw the ;;; exception during the business negotiation rather than via a ;;; runtime refusal to publish. ;;; ;;; Note that, in this publication model, any agreement that the ;;; repository makes to publish the RE's output is conditional upon ;;; the object to be published passing all of its checks. ;;; How do we construct publication URIs (which also go into some of ;;; the X.509 extensions in the resource certs)? We create CAs on the ;;; fly in response to what we learn from our parent, so it's hard to ;;; preconfigure this. This mechanism is still under discussion, the ;;; following is my version of it. ;;; ;;; At least for purposes of discussion, break the publication ;;; directory URI into three pieces: head/middle/tail/. ;;; ;;; head is a URI within the repository with which this RE publishes; ;;; this is either per-parent or per-class-per-parent, but the latter ;;; is hard to preconfigure because we only find out about classes on ;;; the fly. So, for the moment, assume it's per-parent. We're only ;;; allowed to publish stuff here because we have a business ;;; relationship with the repository, so at some level this has to be ;;; preconfigured anyway, along with the repository TA and contact ;;; URI. In theory we could negotiate a location within the ;;; repository on the fly, but let's try to keep this simple. ;;; ;;; Middle may come from this RE's parent. If the parent happens to ;;; be using the same repository as this RE is, the parent can tell us ;;; (currently via an attribute I added to the up-down protocol for ;;; this purpose) a URI under which it gives us permission to lodge. ;;; If the head URI (configured above) is not a prefix of the URI we ;;; get from the parent, we don't have permission to publish under the ;;; parent and middle is null. In essence, middle is the parent's ;;; advice on where to put this particular CA's outputs in order to ;;; get the nice hierarchical properties we want. ;;; ;;; Tail is something this RE makes up. It's per-CA, and all that ;;; really matters is that it's stable. It could be gensymed, or ;;; could be our internal name for the CA, whatever. ;;; ;;; Publication itself always requires a business signature ;;; (demonstrating that we have the right to publish in this ;;; repository at all) and may also require enough of the RPKI cert ;;; chain to demonstrate that this RE's parent has given this RE ;;; permission to publish under a particular URI. Thing that needs to ;;; be proven is that publication client A is not stepping on ;;; publication client B even when B is A's parent. ;;; Signed manifests must be supplied by the RE, as they must be ;;; signed by an EE cert issued by the CA that issues (or signs, in ;;; the case of non-cert objects) everything else in the SIA ;;; collection. This EE cert should probably just use the RFC 3779 ;;; inherit bits as an easy way of inheriting all the resources of the ;;; CA cert. So the publication operation supplies exactly one new ;;; manifest and zero or more other objects; everything in the ;;; publication PDU is published as an atomic operation, ie, if any of ;;; it can't be published, none of it is published. (publish-thing :publication-uri uri-of-thing-we-are-publishing :credential-certs (cert ....) :manifest manifest (:thing crl1 :thing-type :crl) (:thing cert1 :thing-type :cert) (:thing cert2 :thing-type :cert) ... ...) => () ;;; thing is an object (certificate, CRL, ROA) signed by the private ;;; key associated with a resource certificate held by the entity ;;; sending the (publish-thing) request. :thing-type may not be ;;; strictly necessary. ;;; ;;; credential-certs is a set of whatever resource certificates are ;;; needed to demonstrate to the repository engine that the entity ;;; requesting publication is making a legitimate publication request. ;;; Goal (2), above, requires the requestor to supply the resource ;;; certificate chain up to the parent to demonstrate that the parent ;;; has approved (signed) the requested SIA. Goal (3), above, would ;;; require supplying the cert chain back to some resource trust ;;; anchor established as part of the business relationship between ;;; requestor and repository operator. ;;; Hmm, the above completely ignores deletion. Geoff's docs say that ;;; when a resource class disappears we're supposed to withdraw all ;;; certs, CRLs, and manifests associated with that resource class ;;; from the publication point. Strictly speaking, this isn't ;;; necessary, since the parent has presumably CRLed the subtree in ;;; question, but it'd be polite to relying parties, to avoid wasting ;;; their time.