-*- Text -*- $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. @section Terminology - IRBE: Internet Registry Back End - IRDB: Internet Registry Data Base @section Protocol operations between IRBE and RPKI engine The left-right protocol is really two separate client/server protocols over separate channels. The IRBE is the client for one of the subprotocols, the RPKI engine is the client for the other. @subsection Operations initiated by the IRBE This part of the protcol uses a kind of message-passing. Each object that the RPKI engine knows about takes five messages: "create", "set", "get", "list", and "destroy". Actions which are not just data operations on objects are handled via an SNMP-like mechanism, as if they were fields to be set. For example, to generate a keypair one "sets" the "generate-keypair" field of a BSC object, even though there is no such field in the object itself as stored in SQL. This is a bit of a kludge, but the reason for doing it as if these were variables being set is to allow composite operations such as creating a BSC, populating all of its data fields, and generating a keypair, all as a single operation. With this model, that's trivial, otherwise it's at least two round trips. Fields can be set in either "create" or "set" operations, the difference just being whether the object already exists. A "get" operation returns all visible fields of the object. A "list" operation returns a list containing what "get" would have returned on each of those objects. Left-right protocol objects are encoded as signed CMS messages containing XML as eContent and using an eContentType OID of id-ct-xml (1.2.840.113549.1.9.16.1.28). These CMS messages are in turn passed as the data for HTTPS POST operations, with an HTTP content type of "application/x-rpki" for both the POST data and the response data. All operations allow an optional "tag" attribute which can be any alphanumeric token. The main purpose of the tag attribute is to allow @subsubsection object A object represents one virtual RPKI engine. In simple cases where the RPKI engine operator operates the engine only on their own behalf, there will only be one object, representing the engine operator's organization, but in environments where the engine operator hosts other entities, there will be one object per hosted entity (probably including the engine operator's own organization, considered as a hosted customer of itself). Some of the RPKI engine's configured parameters and data are shared by all hosted entities, but most are tied to a specific object. Data which are shared by all hosted entities are referred to as "per-engine" data, data which are specific to a particular object are "per-self" data. Since all other RPKI engine objects refer to a object via a "self_id" value, one must create a object before one can usefully configure any other left-right protocol objects. Payload data which can be configured in a object: @li use_hsm (attribute) Whether to use a Hardware Signing Module. At present this option has no effect, as the implementation does not yet support HSMs. @li crl_interval (attribute) Positive integer representing the planned lifetime of an RPKI CRL for this , measured in seconds. @li regen_margin (attribute) Positive integer representing how long before expiration of an RPKI certificiate a new one should be generated, measured in seconds. At present this only affects the one-off EE certificates associated with ROAs. @li bpki_cert (subelement) BPKI CA certificate for this . This is used as part of the certificate chain when validating incoming TLS and CMS messages, and should be the issuer of cross-certification BPKI certificates used in , , and objects. If the bpki_glue certificate is in use (below), the bpki_cert certificate should be issued by the bpki_glue certificate; otherwise, the bpki_cert certificate should be issued by the per-engine bpki_ta certificate. @li bpki_glue (subelement) Another BPKI CA certificate for this , usually not needed. Certain pathological cross-certification cases require a two-certificate chain due to issuer name conflicts. If used, the bpki_glue certificate should be the issuer of the bpki_cert certificate and should be issued by the per-engine bpki_ta certificate; if not needed, the bpki_glue certificate should be left unset. Control attributes that can be set to "yes" to force actions: @li rekey Start a key rollover for every RPKI CA associated with every object associated with this object. This is the first phase of a key rollover operation. @li revoke Revoke any remaining certificates for any expired key associated with any RPKI CA for any object associated with this object. This is the second (cleanup) phase for a key rollover operation; it's separate from the first phase to leave time for new RPKI certificates to propegate and be installed. @li reissue Not implemented, may be removed from protocol. Original theory was that this operation would force reissuance of any object with a changed key, but as that happens automatically as part of the key rollover mechanism this operation seems unnecessary. @li run_now Force immediate processing for all tasks associated with this object that would ordinarily be performed under cron. Not currently implemented. @li publish_world_now Force (re)publication of every publishable object for this object. Not currently implemented. Intended to aid in recovery if RPKI engine and publication engine somehow get out of sync. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Business signing key context -- bundles all the stuff we need to ;; sign outgoing CMS messages with a business key. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (biz-signing-context :action :create :self-id 42 (:signing-cert cert1) ;; ;; Actions: ;; (:generate-keypair :key-type :rsa :hash-alg :sha1 :key-length 2048)) => (biz-signing-context :biz-signing-context-id 17 (:pkcs10-cert-request req)) (biz-signing-context :action :set :self-id 42 :biz-signing-context-id 17 (:signing-cert cert2)) => (biz-signing-context :biz-signing-context-id 17) (biz-signing-context :action :get :self-id 42 :biz-signing-context-id 17) => (biz-signing-context :biz-signing-context-id 17 (:signing-cert cert1) (:signing-cert cert2) (:public-key key)) (biz-signing-context :action :list :self-id 42) => ((biz-signing-context :biz-signing-context-id 17 (:signing-cert cert1) (:signing-cert cert2) (:public-key key))) (biz-signing-context :action :destroy :self-id 42 :biz-signing-context-id 17) => (biz-signing-context :biz-signing-context-id 17) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parent context -- represents one parent of this RPKI engine ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (parent :action :create :self-id 42 (:ta ta) (:uri uri) (:sia-base sia-base) (:biz-signing-context biz-signing-context) (:repository repository)) => (parent :parent-id 666) (parent :action :set :self-id 42 :parent-id 666 (:ta ta) (:uri uri) (:sia-base sia-base) (:biz-signing-context biz-signing-context) (:repository repository) ;; ;; Actions: ;; (:rekey) ; Change all keys now (:reissue) ; Reissue all certs with changed keys now (:revoke)) ; Revoke any old keys now => (parent :parent-id 666) (parent :action :get :self-id 42 :parent-id 666) => (parent :parent-id 666 (:ta ta) (:uri uri) (:sia-base sia-base) (:biz-signing-context biz-signing-context) (:repository repository)) (parent :action :list :self-id 42 :parent-id 666) => ((parent :parent-id 666 (:ta ta) (:uri uri) (:sia-base sia-base) (:biz-signing-context biz-signing-context) (:repository repository))) (parent :action :destroy :self-id 42 :parent-id 666) => (parent :parent-id 666) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Child context -- represents one child of this RPKI engine ;; ;; "child-db-id" may be unnecessary -- old API had both "child" and ;; "child-id", the second of which was a settable attribute of child, ;; I'm not quite sure what it was, so here I'm calling it child-db-id ;; in case we need it for something. Perhaps this corresponds to the ;; optional child ID in the list-resources callback to the IRBE? ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (child :action :create :self-id 42 (:ta ta) (:biz-signing-context biz-signing-context) (:child-db-id child-db-id)) => (child :child-id 3) (child :action :set :self-id 42 :child-id 3 (:ta ta) (:biz-signing-context biz-signing-context) (:child-db-id child-db-id) (:reissue)) ; Reissue any certs to this child now => (child :child-id 3) (child :action :get :self-id 42 :child-id 3) => (child :child-id 3 (:ta ta) (:biz-signing-context biz-signing-context) (:child-db-id child-db-id)) (child :action :list :self-id 42 :child-id 3) => ((child :child-id 3 (:ta ta) (:biz-signing-context biz-signing-context) (:child-db-id child-db-id))) (child :action :destroy :self-id 42 :child-id 3) => (child :child-id 3) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Repository context -- represents one repository in which this RPKI engine ;; publishes objects it signs. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (repository :action :create :self-id 42 (:uri uri) (:ta ta) (:biz-signing-context biz-signing-context)) => (repository :repository-id 120) (repository :action :set :self-id 42 :repository-id 120 (:uri uri) (:ta ta) (:biz-signing-context biz-signing-context)) => (repository :repository-id 120) (repository :action :get :self-id 42 :repository-id 120) => (repository :repository-id 120 (:uri uri) (:ta ta) (:biz-signing-context biz-signing-context)) (repository :action :list :self-id 42 :repository-id 120) => ((repository :repository-id 120 (:uri uri) (:ta ta) (:biz-signing-context biz-signing-context))) (repository :action :destroy :self-id 42 :repository-id 120) => (repository :repository-id 120) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Route Origin objects (prototype and control for ROAs) ;; ;; Previous versions of this protocol handled this via queries from ;; the RPKI engine back into the IRBE, but the design group now believes that ;; an imperative interface makes more sense. We stick to the same ;; general object model used above because ROAs are published objects, ;; thus the IRBE presumably wants some kind of handle on the ROA. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (route-origin :action :create :self-id 42) => (route-origin :route-origin-id 88) (route-origin :action :set :self-id 42 :route-origin-id 88 :as-number 12345 :publish :yes (:ipv4-prefix 10.0.0.44 32) (:ipv4-range 10.2.0.6 10.2.0.77) (:ipv6-prefix 2002:a00:: 48) (:ipv6-range 2002:a02:6:: 2002:a02:4d::)) => (route-origin :route-origin-id 88) (route-origin :action :get :self-id 42 :route-origin-id 88) => (route-origin :route-origin-id 88 (:as-number 12345) (:ipv4-prefix 10.0.0.44 32) (:ipv4-range 10.2.0.6 10.2.0.77) (:ipv6-prefix 2002:a00:: 48) (:ipv6-range 2002:a02:6:: 2002:a02:4d::)) (route-origin :action :list :self-id 42) => ((route-origin :route-origin-id 88 (:as-number 12345) (:ipv4-prefix 10.0.0.44 32) (:ipv4-range 10.2.0.6 10.2.0.77) (:ipv6-prefix 2002:a00:: 48) (:ipv6-range 2002:a02:6:: 2002:a02:4d::))) (route-origin :action :destroy :self-id 42 :route-origin-id 88) => (route-origin :route-origin-id 88) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; "Blind object signing" would probably be another imperative message ;; to be added above, similar to (route-origin). ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Protocol operations between IRBE and RPKI engine. ;;; ;;; 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 RPKI engine. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (list-resources :self-id 42 ; issuer id :child id) ; subject id => (resources :valid-until 2008-04-01T00:00:00Z ((:ipv4-prefix 10.0.0.44 32) (:ipv4-prefix 10.3.0.44 32) (:ipv6-prefix fe80:dead:beef:: 48) (:as-number 666)) ((:subject-name "wombats are us") ; Allowed in protocol, but RPKI engine may reject with error (:ipv4-prefix 10.2..0.6 32) (:ipv6-prefix fe80:dead:beef:: 48) (:ipv6-range fe80:dead:beef:: fe80:dead:beef::49) (:as-number 666)) ...) (report-error :self-id 42 :error-token :your-hair-is-on-fire :bag-of-data whatever) => ()