;;; -*- Lisp -*- ;;; $URL$ ;;; $Id$ ;;; ;;; 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 ;;; Current problems: ;;; Need revoke and rekey operations for RPKI keys. First problem is ;;; how does the IRBE name the key that is to roll if keypairs are ;;; created on the fly? Hmm. We can say "roll all the keys ;;; associated with this child" easily enough, will that suffice? ;;; 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. At least for purposes of discussion, break the ;;; publication directory URI into three pieces: head/middle/tail/. ;;; This mechanism is still under discussion, the following is my ;;; version of it. ;;; ;;; 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. ;;; Explanation for many-many mapping beween CA and child objects ;;; (courtesy of RobL): Each child is an entity; each CA can have ;;; multiple children, and each child can hold certs from multiple ;;; CAs. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Protocol operations between IRBE and RE. ;;; ;;; This is really two separate protocols over channels that might or ;;; not be the same. Both are client/server protocols, but for some ;;; the RE is the client and for others the IRBE is the client. ;;; ;;; This set of operations are initiated by the IRBE. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; "Self" ID context -- one RE instance. In degenerate case there ;; will be only one, but in hosting environments there might be many. (create-self-id) => (self-id) (destroy-self-id :self-id 42) => () (list-self-ids) => (self-id ...) ;; RobK wonders whether there needs to be an operation that blows away ;; most of the context but preserves things like audit logs. No ;; current consensus on need for this. (get-preference :self-id 42 :preference-name :favorite-color) => ("obsidian") (set-preference :self-id 42 :name :favorite-color :value "obsidian") => () ;; Extensions might also show up as preferences that nobody but this ;; IRBE operator has ever heard of. ;; Business signing key context -- Bundles all the stuff we need to ;; sign outgoing CMS messages with a business key. ;; ;; At one point creating a business signing context also created the ;; key, but that makes key rollover painful when we have many objects ;; all pointing at the same signing context. Easier just to leave all ;; the object links in place and roll the key explictly. (create-biz-signing-context :self-id 42) => (biz-signing-context-id) (destroy-biz-signing-context :self-id 42 :biz-signing-context-id biz-context-id) => () (list-biz-signing-contexts :self-id 42) => (biz-signing-context-id ...) (generate-biz-signing-keypair :self-id 42 :biz-signing-context-id foo &optional :key-type :rsa :key-length 2048 :hash-alg :sha1) => (pkcs10-cert-request) (get-biz-signing-certs :self-id 42 :biz-signing-context-id splat) => (cert ...) (set-biz-signing-certs :self-id 42 :biz-signing-context-id splat :certs (cert ...)) => () ;; Parent context -- represents one parent of this RE (create-parent-context :self-id 42) => (parent) (destroy-parent-context :self-id 42 :parent foo) => () (list-parents :self-id 42) => (parent ...) (get-parent-ta :self-id 42 :parent foo) => (ta) (set-parent-ta :self-id 42 :parent foo :ta ta) => () (get-parent-uri :self-id 42 :parent foo) => (uri) (set-parent-uri :self-id 42 :parent foo :uri uri) => () (get-parent-biz-signing-context :self-id 42 :parent foo) => (biz-signing-context) (set-parent-biz-signing-context :self-id 42 :parent foo :biz-signing-context bar) => () (get-parent-repository :self-id 42 :parent foo) => (repository) (set-parent-repository :self-id 42 :parent foo :repository bar) => () ;; Child context -- represents one child of this RE (create-child :self-id 42) => (child) (destroy-child :self-id 42 :child bar) => () (list-children :self-id id) => (child ...) (get-child-id :self-id 42 :child foo) => (child-id) (set-child-id :self-id 42 :child foo :id bar) => () (get-child-ta :self-id 42 :child foo) => (ta) (set-child-ta :self-id 42 :child foo :ta bar) => () (get-child-biz-signing-context :self-id 42 :child foo) => (signing-context) (set-child-biz-signing-context :self-id 42 :child foo :biz-signing-context bar) => () ;; Repository context -- represents one repository in which this RE ;; publishes objects it signs. (create-repository :self-id 42) => (repository) (destroy-repository :self-id 42 :repository foo) => () (list-repositories :self-id 42) => (repository ...) (get-repository-biz-signing-context :self-id 42 :repository foo) => (signing-context) (set-repository-biz-signing-context :self-id 42 :repository foo :biz-signing-context bar) => () (get-repository-uri :self-id 42 :repository foo) => (uri) (set-repository-uri :self-id 42 :repository foo :uri uri) => () (get-repository-ta :self-id 42 :repository foo) => (ta) (set-repository-ta :self-id 42 :repository foo :ta ta) => () ;; Force normal processing for a particular self-id right now. (please-run-this-self-id-now :self-id 42) => () ;; Publish everything we've got right now. (please-publish-world-right-now :self-id 42) => () ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Protocol operations between IRBE and RE. ;;; ;;; This is really two separate protocols over channels that might or ;;; not be the same. Both are client/server protocols, but for some ;;; the rpki engine and for others the irbe is the client. ;;; ;;; This set of operations are initiated by the RE. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (list-resources :self-id 42 ; issuer id &optional ; If left off, we're asking about self rather than child :child id) ; subject id => ((:ipv4-address "10.0.0.44/32" "10.3.0.44/32") (:ipv6-address "fe80:dead:beef::/24") (:as-number "666") ...) (list-rights-to-route :self-id 42) ; Self => ((as-number :ipv4 prefix-or-range :ipv6 prefix-or-range ...) (as-number "ipv6 prefix-or-range :ipv6 prefix-or-range :ipv4 prefix-or-range ...) ...) (report-error :self-id 42 :error-token :your-hair-is-on-fire :bag-of-data whatever) => ()