1 use std::{collections::HashMap, fmt};
2 
3 use rpki::repository::crypto::KeyIdentifier;
4 
5 use crate::{
6     commons::{
7         api::{
8             AspaCustomer, AspaDefinition, AspaProvidersUpdate, ChildHandle, Handle, IssuanceRequest, IssuedCert,
9             ObjectName, ParentCaContact, ParentHandle, ParentResourceClassName, RcvdCert, RepositoryContact,
10             ResourceClassName, ResourceSet, RevocationRequest, RevokedObject, RoaAggregateKey, RtaName, SuspendedCert,
11             TaCertDetails, UnsuspendedCert,
12         },
13         crypto::{IdCert, KrillSigner},
14         eventsourcing::StoredEvent,
15         KrillResult,
16     },
17     daemon::ca::{
18         AggregateRoaInfo, AspaInfo, CertifiedKey, PreparedRta, PublishedRoa, Rfc8183Id, RoaInfo, RouteAuthorization,
19         SignedRta,
20     },
21 };
22 
23 //------------ Ini -----------------------------------------------------------
24 
25 pub type Ini = StoredEvent<IniDet>;
26 
27 //------------ IniDet --------------------------------------------------------
28 
29 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
30 pub struct IniDet {
31     id: Rfc8183Id,
32 }
33 
34 impl IniDet {
unpack(self) -> Rfc8183Id35     pub fn unpack(self) -> Rfc8183Id {
36         self.id
37     }
38 }
39 
40 impl IniDet {
new(handle: &Handle, id: Rfc8183Id) -> Ini41     pub fn new(handle: &Handle, id: Rfc8183Id) -> Ini {
42         Ini::new(handle, 0, IniDet { id })
43     }
44 
init(handle: &Handle, signer: &KrillSigner) -> KrillResult<Ini>45     pub fn init(handle: &Handle, signer: &KrillSigner) -> KrillResult<Ini> {
46         let id = Rfc8183Id::generate(signer)?;
47         Ok(Self::new(handle, id))
48     }
49 }
50 
51 impl fmt::Display for IniDet {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result52     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53         write!(f, "Initialized with ID key hash: {}", self.id.key_hash())?;
54         Ok(())
55     }
56 }
57 
58 //------------ RoaUpdates --------------------------------------------------
59 
60 /// Describes an update to the set of ROAs under a ResourceClass.
61 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
62 pub struct RoaUpdates {
63     #[serde(
64         skip_serializing_if = "HashMap::is_empty",
65         default = "HashMap::new",
66         with = "updated_sorted_map"
67     )]
68     updated: HashMap<RouteAuthorization, RoaInfo>,
69 
70     #[serde(
71         skip_serializing_if = "HashMap::is_empty",
72         default = "HashMap::new",
73         with = "removed_sorted_map"
74     )]
75     removed: HashMap<RouteAuthorization, RevokedObject>,
76 
77     #[serde(
78         skip_serializing_if = "HashMap::is_empty",
79         default = "HashMap::new",
80         with = "aggregate_updated_sorted_map"
81     )]
82     aggregate_updated: HashMap<RoaAggregateKey, AggregateRoaInfo>,
83 
84     #[serde(
85         skip_serializing_if = "HashMap::is_empty",
86         default = "HashMap::new",
87         with = "aggregate_removed_sorted_map"
88     )]
89     aggregate_removed: HashMap<RoaAggregateKey, RevokedObject>,
90 }
91 
92 mod updated_sorted_map {
93     use super::*;
94 
95     use serde::de::{Deserialize, Deserializer};
96     use serde::ser::Serializer;
97 
98     #[derive(Debug, Deserialize)]
99     struct Item {
100         auth: RouteAuthorization,
101         roa: RoaInfo,
102     }
103 
104     #[derive(Debug, Serialize)]
105     struct ItemRef<'a> {
106         auth: &'a RouteAuthorization,
107         roa: &'a RoaInfo,
108     }
109 
serialize<S>(map: &HashMap<RouteAuthorization, RoaInfo>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,110     pub fn serialize<S>(map: &HashMap<RouteAuthorization, RoaInfo>, serializer: S) -> Result<S::Ok, S::Error>
111     where
112         S: Serializer,
113     {
114         let mut sorted_vec: Vec<ItemRef> = map.iter().map(|(auth, roa)| ItemRef { auth, roa }).collect();
115         sorted_vec.sort_by_key(|el| el.auth);
116 
117         serializer.collect_seq(sorted_vec)
118     }
119 
deserialize<'de, D>(deserializer: D) -> Result<HashMap<RouteAuthorization, RoaInfo>, D::Error> where D: Deserializer<'de>,120     pub fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<RouteAuthorization, RoaInfo>, D::Error>
121     where
122         D: Deserializer<'de>,
123     {
124         let mut map = HashMap::new();
125         for item in Vec::<Item>::deserialize(deserializer)? {
126             map.insert(item.auth, item.roa);
127         }
128         Ok(map)
129     }
130 }
131 
132 mod aggregate_updated_sorted_map {
133     use super::*;
134 
135     use serde::de::{Deserialize, Deserializer};
136     use serde::ser::Serializer;
137 
138     #[derive(Debug, Deserialize)]
139     struct Item {
140         agg: RoaAggregateKey,
141         roa: AggregateRoaInfo,
142     }
143 
144     #[derive(Debug, Serialize)]
145     struct ItemRef<'a> {
146         agg: &'a RoaAggregateKey,
147         roa: &'a AggregateRoaInfo,
148     }
149 
serialize<S>(map: &HashMap<RoaAggregateKey, AggregateRoaInfo>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,150     pub fn serialize<S>(map: &HashMap<RoaAggregateKey, AggregateRoaInfo>, serializer: S) -> Result<S::Ok, S::Error>
151     where
152         S: Serializer,
153     {
154         let mut sorted_vec: Vec<ItemRef> = map.iter().map(|(agg, roa)| ItemRef { agg, roa }).collect();
155         sorted_vec.sort_by_key(|el| el.agg);
156 
157         serializer.collect_seq(sorted_vec)
158     }
159 
deserialize<'de, D>(deserializer: D) -> Result<HashMap<RoaAggregateKey, AggregateRoaInfo>, D::Error> where D: Deserializer<'de>,160     pub fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<RoaAggregateKey, AggregateRoaInfo>, D::Error>
161     where
162         D: Deserializer<'de>,
163     {
164         let mut map = HashMap::new();
165         for item in Vec::<Item>::deserialize(deserializer)? {
166             map.insert(item.agg, item.roa);
167         }
168         Ok(map)
169     }
170 }
171 
172 mod removed_sorted_map {
173     use super::*;
174 
175     use serde::de::{Deserialize, Deserializer};
176     use serde::ser::Serializer;
177 
178     #[derive(Debug, Deserialize)]
179     struct Item {
180         auth: RouteAuthorization,
181         removed: RevokedObject,
182     }
183 
184     #[derive(Debug, Serialize)]
185     struct ItemRef<'a> {
186         auth: &'a RouteAuthorization,
187         removed: &'a RevokedObject,
188     }
189 
serialize<S>(map: &HashMap<RouteAuthorization, RevokedObject>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,190     pub fn serialize<S>(map: &HashMap<RouteAuthorization, RevokedObject>, serializer: S) -> Result<S::Ok, S::Error>
191     where
192         S: Serializer,
193     {
194         let mut sorted_vec: Vec<ItemRef> = map.iter().map(|(auth, removed)| ItemRef { auth, removed }).collect();
195         sorted_vec.sort_by_key(|el| el.auth);
196 
197         serializer.collect_seq(sorted_vec)
198     }
199 
deserialize<'de, D>(deserializer: D) -> Result<HashMap<RouteAuthorization, RevokedObject>, D::Error> where D: Deserializer<'de>,200     pub fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<RouteAuthorization, RevokedObject>, D::Error>
201     where
202         D: Deserializer<'de>,
203     {
204         let mut map = HashMap::new();
205         for item in Vec::<Item>::deserialize(deserializer)? {
206             map.insert(item.auth, item.removed);
207         }
208         Ok(map)
209     }
210 }
211 
212 mod aggregate_removed_sorted_map {
213     use super::*;
214 
215     use serde::de::{Deserialize, Deserializer};
216     use serde::ser::Serializer;
217 
218     #[derive(Debug, Deserialize)]
219     struct Item {
220         agg: RoaAggregateKey,
221         removed: RevokedObject,
222     }
223 
224     #[derive(Debug, Serialize)]
225     struct ItemRef<'a> {
226         agg: &'a RoaAggregateKey,
227         removed: &'a RevokedObject,
228     }
229 
serialize<S>(map: &HashMap<RoaAggregateKey, RevokedObject>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,230     pub fn serialize<S>(map: &HashMap<RoaAggregateKey, RevokedObject>, serializer: S) -> Result<S::Ok, S::Error>
231     where
232         S: Serializer,
233     {
234         let mut sorted_vec: Vec<ItemRef> = map.iter().map(|(agg, removed)| ItemRef { agg, removed }).collect();
235         sorted_vec.sort_by_key(|el| el.agg);
236 
237         serializer.collect_seq(sorted_vec)
238     }
239 
deserialize<'de, D>(deserializer: D) -> Result<HashMap<RoaAggregateKey, RevokedObject>, D::Error> where D: Deserializer<'de>,240     pub fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<RoaAggregateKey, RevokedObject>, D::Error>
241     where
242         D: Deserializer<'de>,
243     {
244         let mut map = HashMap::new();
245         for item in Vec::<Item>::deserialize(deserializer)? {
246             map.insert(item.agg, item.removed);
247         }
248         Ok(map)
249     }
250 }
251 
252 impl Default for RoaUpdates {
default() -> Self253     fn default() -> Self {
254         RoaUpdates {
255             updated: HashMap::new(),
256             removed: HashMap::new(),
257             aggregate_updated: HashMap::new(),
258             aggregate_removed: HashMap::new(),
259         }
260     }
261 }
262 
263 impl RoaUpdates {
is_empty(&self) -> bool264     pub fn is_empty(&self) -> bool {
265         self.updated.is_empty()
266             && self.removed.is_empty()
267             && self.aggregate_updated.is_empty()
268             && self.aggregate_removed.is_empty()
269     }
270 
contains_changes(&self) -> bool271     pub fn contains_changes(&self) -> bool {
272         !self.is_empty()
273     }
274 
update(&mut self, auth: RouteAuthorization, roa: RoaInfo)275     pub fn update(&mut self, auth: RouteAuthorization, roa: RoaInfo) {
276         self.updated.insert(auth, roa);
277     }
278 
remove(&mut self, auth: RouteAuthorization, revoke: RevokedObject)279     pub fn remove(&mut self, auth: RouteAuthorization, revoke: RevokedObject) {
280         self.removed.insert(auth, revoke);
281     }
282 
remove_aggregate(&mut self, key: RoaAggregateKey, revoke: RevokedObject)283     pub fn remove_aggregate(&mut self, key: RoaAggregateKey, revoke: RevokedObject) {
284         self.aggregate_removed.insert(key, revoke);
285     }
286 
update_aggregate(&mut self, key: RoaAggregateKey, aggregate: AggregateRoaInfo)287     pub fn update_aggregate(&mut self, key: RoaAggregateKey, aggregate: AggregateRoaInfo) {
288         self.aggregate_updated.insert(key, aggregate);
289     }
290 
added_roas(&self) -> KrillResult<HashMap<ObjectName, PublishedRoa>>291     pub fn added_roas(&self) -> KrillResult<HashMap<ObjectName, PublishedRoa>> {
292         let mut res = HashMap::new();
293 
294         for (auth, simple) in &self.updated {
295             let roa = simple.roa().clone();
296             let name = ObjectName::from(auth);
297 
298             res.insert(name, PublishedRoa::new(roa));
299         }
300 
301         for (agg_key, agg_info) in &self.aggregate_updated {
302             let roa = agg_info.roa_info().roa().clone();
303             let name = ObjectName::from(agg_key);
304 
305             res.insert(name, PublishedRoa::new(roa));
306         }
307 
308         Ok(res)
309     }
310 
removed_roas(&self) -> Vec<ObjectName>311     pub fn removed_roas(&self) -> Vec<ObjectName> {
312         let mut res = vec![];
313 
314         for simple in self.removed.keys() {
315             res.push(ObjectName::from(simple))
316         }
317 
318         for agg in self.aggregate_removed.keys() {
319             res.push(ObjectName::from(agg))
320         }
321 
322         res
323     }
324 
325     #[allow(clippy::type_complexity)]
unpack( self, ) -> ( HashMap<RouteAuthorization, RoaInfo>, HashMap<RouteAuthorization, RevokedObject>, HashMap<RoaAggregateKey, AggregateRoaInfo>, HashMap<RoaAggregateKey, RevokedObject>, )326     pub fn unpack(
327         self,
328     ) -> (
329         HashMap<RouteAuthorization, RoaInfo>,
330         HashMap<RouteAuthorization, RevokedObject>,
331         HashMap<RoaAggregateKey, AggregateRoaInfo>,
332         HashMap<RoaAggregateKey, RevokedObject>,
333     ) {
334         (
335             self.updated,
336             self.removed,
337             self.aggregate_updated,
338             self.aggregate_removed,
339         )
340     }
341 }
342 
343 impl fmt::Display for RoaUpdates {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result344     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
345         if !self.updated.is_empty() {
346             write!(f, "Updated single VRP ROAs: ")?;
347             for roa in self.updated.keys() {
348                 write!(f, "{} ", ObjectName::from(roa))?;
349             }
350         }
351         if !self.removed.is_empty() {
352             write!(f, "Removed single VRP ROAs: ")?;
353             for roa in self.removed.keys() {
354                 write!(f, "{} ", ObjectName::from(roa))?;
355             }
356         }
357         if !self.aggregate_updated.is_empty() {
358             write!(f, "Updated ASN aggregated ROAs: ")?;
359             for roa in self.aggregate_updated.keys() {
360                 write!(f, "{} ", ObjectName::from(roa))?;
361             }
362         }
363         if !self.aggregate_removed.is_empty() {
364             write!(f, "Removed ASN aggregated ROAs: ")?;
365             for roa in self.aggregate_removed.keys() {
366                 write!(f, "{} ", ObjectName::from(roa))?;
367             }
368         }
369         Ok(())
370     }
371 }
372 
373 //------------ AspaObjectsUpdates ------------------------------------------
374 
375 #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
376 pub struct AspaObjectsUpdates {
377     #[serde(skip_serializing_if = "Vec::is_empty", default)]
378     updated: Vec<AspaInfo>,
379 
380     #[serde(skip_serializing_if = "Vec::is_empty", default)]
381     removed: Vec<AspaCustomer>,
382 }
383 
384 impl AspaObjectsUpdates {
new(updated: Vec<AspaInfo>, removed: Vec<AspaCustomer>) -> Self385     pub fn new(updated: Vec<AspaInfo>, removed: Vec<AspaCustomer>) -> Self {
386         AspaObjectsUpdates { updated, removed }
387     }
388 
for_new_aspa_info(new_aspa: AspaInfo) -> Self389     pub fn for_new_aspa_info(new_aspa: AspaInfo) -> Self {
390         AspaObjectsUpdates {
391             updated: vec![new_aspa],
392             removed: vec![],
393         }
394     }
395 
add_updated(&mut self, update: AspaInfo)396     pub fn add_updated(&mut self, update: AspaInfo) {
397         self.updated.push(update)
398     }
399 
add_removed(&mut self, customer: AspaCustomer)400     pub fn add_removed(&mut self, customer: AspaCustomer) {
401         self.removed.push(customer)
402     }
403 
is_empty(&self) -> bool404     pub fn is_empty(&self) -> bool {
405         self.updated.is_empty() && self.removed.is_empty()
406     }
407 
contains_changes(&self) -> bool408     pub fn contains_changes(&self) -> bool {
409         !self.is_empty()
410     }
411 
unpack(self) -> (Vec<AspaInfo>, Vec<AspaCustomer>)412     pub fn unpack(self) -> (Vec<AspaInfo>, Vec<AspaCustomer>) {
413         (self.updated, self.removed)
414     }
415 
updated(&self) -> &Vec<AspaInfo>416     pub fn updated(&self) -> &Vec<AspaInfo> {
417         &self.updated
418     }
419 
removed(&self) -> &Vec<AspaCustomer>420     pub fn removed(&self) -> &Vec<AspaCustomer> {
421         &self.removed
422     }
423 }
424 
425 //------------ ChildCertificateUpdates -------------------------------------
426 
427 /// Describes an update to the set of ROAs under a ResourceClass.
428 #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
429 pub struct ChildCertificateUpdates {
430     issued: Vec<IssuedCert>,
431     removed: Vec<KeyIdentifier>,
432     suspended: Vec<SuspendedCert>,
433     unsuspended: Vec<UnsuspendedCert>,
434 }
435 
436 impl ChildCertificateUpdates {
new( issued: Vec<IssuedCert>, removed: Vec<KeyIdentifier>, suspended: Vec<SuspendedCert>, unsuspended: Vec<UnsuspendedCert>, ) -> Self437     pub fn new(
438         issued: Vec<IssuedCert>,
439         removed: Vec<KeyIdentifier>,
440         suspended: Vec<SuspendedCert>,
441         unsuspended: Vec<UnsuspendedCert>,
442     ) -> Self {
443         ChildCertificateUpdates {
444             issued,
445             removed,
446             suspended,
447             unsuspended,
448         }
449     }
450 
is_empty(&self) -> bool451     pub fn is_empty(&self) -> bool {
452         self.issued.is_empty() && self.removed.is_empty() && self.suspended.is_empty() && self.unsuspended.is_empty()
453     }
454 
455     /// Add an issued certificate to the current set of issued certificates.
456     /// Note that this is typically a newly issued certificate, but it can
457     /// also be a previously issued certificate which had been suspended and
458     /// is now unsuspended.
issue(&mut self, new: IssuedCert)459     pub fn issue(&mut self, new: IssuedCert) {
460         self.issued.push(new);
461     }
462 
463     /// Remove certificates for a key identifier. This will ensure that they
464     /// are revoked.
remove(&mut self, ki: KeyIdentifier)465     pub fn remove(&mut self, ki: KeyIdentifier) {
466         self.removed.push(ki);
467     }
468 
469     /// List all currently issued (not suspended) certificates.
issued(&self) -> &Vec<IssuedCert>470     pub fn issued(&self) -> &Vec<IssuedCert> {
471         &self.issued
472     }
473 
474     /// List all removals (revocations).
removed(&self) -> &Vec<KeyIdentifier>475     pub fn removed(&self) -> &Vec<KeyIdentifier> {
476         &self.removed
477     }
478 
479     /// Suspend a certificate
suspend(&mut self, suspended_cert: SuspendedCert)480     pub fn suspend(&mut self, suspended_cert: SuspendedCert) {
481         self.suspended.push(suspended_cert);
482     }
483 
484     /// List all suspended certificates in this update.
suspended(&self) -> &Vec<SuspendedCert>485     pub fn suspended(&self) -> &Vec<SuspendedCert> {
486         &self.suspended
487     }
488 
489     /// Unsuspend a certificate
unsuspend(&mut self, unsuspended_cert: UnsuspendedCert)490     pub fn unsuspend(&mut self, unsuspended_cert: UnsuspendedCert) {
491         self.unsuspended.push(unsuspended_cert);
492     }
493 
494     /// List all unsuspended certificates in this update.
unsuspended(&self) -> &Vec<UnsuspendedCert>495     pub fn unsuspended(&self) -> &Vec<UnsuspendedCert> {
496         &self.unsuspended
497     }
498 
unpack( self, ) -> ( Vec<IssuedCert>, Vec<KeyIdentifier>, Vec<SuspendedCert>, Vec<UnsuspendedCert>, )499     pub fn unpack(
500         self,
501     ) -> (
502         Vec<IssuedCert>,
503         Vec<KeyIdentifier>,
504         Vec<SuspendedCert>,
505         Vec<UnsuspendedCert>,
506     ) {
507         (self.issued, self.removed, self.suspended, self.unsuspended)
508     }
509 }
510 
511 //------------ Evt ---------------------------------------------------------
512 
513 pub type CaEvt = StoredEvent<CaEvtDet>;
514 
515 //------------ EvtDet -------------------------------------------------------
516 
517 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
518 #[allow(clippy::large_enum_variant)]
519 #[serde(rename_all = "snake_case")]
520 #[serde(tag = "type")]
521 pub enum CaEvtDet {
522     // Being a Trust Anchor
523     TrustAnchorMade {
524         ta_cert_details: TaCertDetails,
525     },
526 
527     // Being a parent Events
528     /// A child was added to this (parent) CA
529     ChildAdded {
530         child: ChildHandle,
531         id_cert: IdCert,
532         resources: ResourceSet,
533     },
534 
535     /// A certificate was issued to the child of this (parent) CA
536     ChildCertificateIssued {
537         child: ChildHandle,
538         resource_class_name: ResourceClassName,
539         ki: KeyIdentifier,
540     },
541 
542     /// A child key was revoked.
543     ChildKeyRevoked {
544         child: ChildHandle,
545         resource_class_name: ResourceClassName,
546         ki: KeyIdentifier,
547     },
548 
549     /// Child certificates (for potentially multiple children) were updated
550     /// under a CA resource class. I.e. child certificates were issued,
551     /// removed, or suspended.
552     ChildCertificatesUpdated {
553         resource_class_name: ResourceClassName,
554         updates: ChildCertificateUpdates,
555     },
556     ChildUpdatedIdCert {
557         child: ChildHandle,
558         id_cert: IdCert,
559     },
560     ChildUpdatedResources {
561         child: ChildHandle,
562         resources: ResourceSet,
563     },
564     ChildRemoved {
565         child: ChildHandle,
566     },
567 
568     // (Un)Suspend a child events
569     ChildSuspended {
570         child: ChildHandle,
571     },
572     ChildUnsuspended {
573         child: ChildHandle,
574     },
575 
576     // Being a child Events
577     IdUpdated {
578         id: Rfc8183Id,
579     },
580     ParentAdded {
581         parent: ParentHandle,
582         contact: ParentCaContact,
583     },
584     ParentUpdated {
585         parent: ParentHandle,
586         contact: ParentCaContact,
587     },
588     ParentRemoved {
589         parent: ParentHandle,
590     },
591     ResourceClassAdded {
592         resource_class_name: ResourceClassName,
593         parent: ParentHandle,
594         parent_resource_class_name: ParentResourceClassName,
595         pending_key: KeyIdentifier,
596     },
597     ResourceClassRemoved {
598         resource_class_name: ResourceClassName,
599         parent: ParentHandle,
600         revoke_requests: Vec<RevocationRequest>,
601     },
602     CertificateRequested {
603         resource_class_name: ResourceClassName,
604         req: IssuanceRequest,
605         ki: KeyIdentifier, // Also contained in request. Drop?
606     },
607     CertificateReceived {
608         resource_class_name: ResourceClassName,
609         rcvd_cert: RcvdCert,
610         ki: KeyIdentifier, // Also in received cert. Drop?
611     },
612 
613     // Key life cycle
614     KeyRollPendingKeyAdded {
615         // A pending key is added to an existing resource class in order to initiate
616         // a key roll. Note that there will be a separate 'CertificateRequested' event for
617         // this key.
618         resource_class_name: ResourceClassName,
619         pending_key_id: KeyIdentifier,
620     },
621     KeyPendingToNew {
622         // A pending key is marked as 'new' when it has received its (first) certificate.
623         // This means that the key is staged and a mft and crl will be published. According
624         // to RFC 6489 this key should be staged for 24 hours before it is promoted to
625         // become the active key. However, in practice this time can be shortened.
626         resource_class_name: ResourceClassName,
627         new_key: CertifiedKey, // pending key which received a certificate becomes 'new', i.e. it is staged.
628     },
629     KeyPendingToActive {
630         // When a new resource class is created it will have a single pending key only which
631         // is promoted to become the active (current) key for the resource class immediately
632         // after receiving its first certificate. Technically this is not a roll, but a simple
633         // first activation.
634         resource_class_name: ResourceClassName,
635         current_key: CertifiedKey, // there was no current key, pending becomes active without staging when cert is received.
636     },
637     KeyRollActivated {
638         // When a 'new' key is activated (becomes current), the previous current key will be
639         // marked as old and we will request its revocation. Note that any current ROAs and/or
640         // delegated certificates will also be re-issued under the new 'current' key. These changes
641         // are tracked in separate `RoasUpdated` and `ChildCertificatesUpdated` events.
642         resource_class_name: ResourceClassName,
643         revoke_req: RevocationRequest,
644     },
645     KeyRollFinished {
646         // The key roll is finished when the parent confirms that the old key is revoked.
647         // We can remove it and stop publishing its mft and crl.
648         resource_class_name: ResourceClassName,
649     },
650     UnexpectedKeyFound {
651         // This event is generated in case our parent reports keys to us that we do not
652         // believe we have. This should not happen in practice, but this is tracked so that
653         // we can recover from this situation. We can request revocation for all these keys
654         // and create new keys in the RC as needed.
655         resource_class_name: ResourceClassName,
656         revoke_req: RevocationRequest,
657     },
658 
659     // Route Authorizations
660     RouteAuthorizationAdded {
661         // Tracks a single authorization (VRP) which is added. Note that (1) a command to
662         // update ROAs can contain multiple changes in which case multiple events will
663         // result, and (2) we do not have a 'modify' event. Modifications of e.g. the
664         // max length are expressed as a 'removed' and 'added' event in a single transaction.
665         auth: RouteAuthorization,
666     },
667     RouteAuthorizationRemoved {
668         // Tracks a single authorization (VRP) which is removed. See remark for RouteAuthorizationAdded.
669         auth: RouteAuthorization,
670     },
671     RoasUpdated {
672         // Tracks ROA *objects* which are (re-)issued in a resource class.
673         resource_class_name: ResourceClassName,
674         updates: RoaUpdates,
675     },
676 
677     // ASPA
678     AspaConfigAdded {
679         aspa_config: AspaDefinition,
680     },
681     AspaConfigUpdated {
682         customer: AspaCustomer,
683         update: AspaProvidersUpdate,
684     },
685     AspaConfigRemoved {
686         customer: AspaCustomer,
687     },
688     AspaObjectsUpdated {
689         // Tracks ASPA *object* which are (re-)issued in a resource class.
690         resource_class_name: ResourceClassName,
691         updates: AspaObjectsUpdates,
692     },
693 
694     // Publishing
695     RepoUpdated {
696         // Adds the repository contact for this CA so that publication can commence,
697         // and certificates can be requested from parents. Note: the CA can only start
698         // requesting certificates when it knows which URIs it can use.
699         contact: RepositoryContact,
700     },
701 
702     // Rta
703     //
704     // NOTE RTA support is still experimental and incomplete.
705     RtaSigned {
706         // Adds a signed RTA. The RTA can be single signed, or it can
707         // be a multi-signed RTA based on an existing 'PreparedRta'.
708         name: RtaName,
709         rta: SignedRta,
710     },
711     RtaPrepared {
712         // Adds a 'prepared' RTA. I.e. the context of keys which need to be included
713         // in a multi-signed RTA.
714         name: RtaName,
715         prepared: PreparedRta,
716     },
717 }
718 
719 impl CaEvtDet {
720     /// This marks the RFC8183Id as updated
id_updated(handle: &Handle, version: u64, id: Rfc8183Id) -> CaEvt721     pub(super) fn id_updated(handle: &Handle, version: u64, id: Rfc8183Id) -> CaEvt {
722         StoredEvent::new(handle, version, CaEvtDet::IdUpdated { id })
723     }
724 
725     /// This marks a parent as added to the CA.
parent_added(handle: &Handle, version: u64, parent: ParentHandle, contact: ParentCaContact) -> CaEvt726     pub(super) fn parent_added(handle: &Handle, version: u64, parent: ParentHandle, contact: ParentCaContact) -> CaEvt {
727         StoredEvent::new(handle, version, CaEvtDet::ParentAdded { parent, contact })
728     }
729 
730     /// This marks a parent contact as updated
parent_updated( handle: &Handle, version: u64, parent: ParentHandle, contact: ParentCaContact, ) -> CaEvt731     pub(super) fn parent_updated(
732         handle: &Handle,
733         version: u64,
734         parent: ParentHandle,
735         contact: ParentCaContact,
736     ) -> CaEvt {
737         StoredEvent::new(handle, version, CaEvtDet::ParentUpdated { parent, contact })
738     }
739 
child_added( handle: &Handle, version: u64, child: ChildHandle, id_cert: IdCert, resources: ResourceSet, ) -> CaEvt740     pub(super) fn child_added(
741         handle: &Handle,
742         version: u64,
743         child: ChildHandle,
744         id_cert: IdCert,
745         resources: ResourceSet,
746     ) -> CaEvt {
747         StoredEvent::new(
748             handle,
749             version,
750             CaEvtDet::ChildAdded {
751                 child,
752                 id_cert,
753                 resources,
754             },
755         )
756     }
757 
child_updated_cert(handle: &Handle, version: u64, child: ChildHandle, id_cert: IdCert) -> CaEvt758     pub(super) fn child_updated_cert(handle: &Handle, version: u64, child: ChildHandle, id_cert: IdCert) -> CaEvt {
759         StoredEvent::new(handle, version, CaEvtDet::ChildUpdatedIdCert { child, id_cert })
760     }
761 
child_updated_resources( handle: &Handle, version: u64, child: ChildHandle, resources: ResourceSet, ) -> CaEvt762     pub(super) fn child_updated_resources(
763         handle: &Handle,
764         version: u64,
765         child: ChildHandle,
766         resources: ResourceSet,
767     ) -> CaEvt {
768         StoredEvent::new(handle, version, CaEvtDet::ChildUpdatedResources { child, resources })
769     }
770 
child_certificate_issued( handle: &Handle, version: u64, child: ChildHandle, resource_class_name: ResourceClassName, ki: KeyIdentifier, ) -> CaEvt771     pub(super) fn child_certificate_issued(
772         handle: &Handle,
773         version: u64,
774         child: ChildHandle,
775         resource_class_name: ResourceClassName,
776         ki: KeyIdentifier,
777     ) -> CaEvt {
778         StoredEvent::new(
779             handle,
780             version,
781             CaEvtDet::ChildCertificateIssued {
782                 child,
783                 resource_class_name,
784                 ki,
785             },
786         )
787     }
788 
child_revoke_key( handle: &Handle, version: u64, child: ChildHandle, resource_class_name: ResourceClassName, ki: KeyIdentifier, ) -> CaEvt789     pub(super) fn child_revoke_key(
790         handle: &Handle,
791         version: u64,
792         child: ChildHandle,
793         resource_class_name: ResourceClassName,
794         ki: KeyIdentifier,
795     ) -> CaEvt {
796         StoredEvent::new(
797             handle,
798             version,
799             CaEvtDet::ChildKeyRevoked {
800                 child,
801                 resource_class_name,
802                 ki,
803             },
804         )
805     }
806 
child_certificates_updated( handle: &Handle, version: u64, resource_class_name: ResourceClassName, updates: ChildCertificateUpdates, ) -> CaEvt807     pub(super) fn child_certificates_updated(
808         handle: &Handle,
809         version: u64,
810         resource_class_name: ResourceClassName,
811         updates: ChildCertificateUpdates,
812     ) -> CaEvt {
813         StoredEvent::new(
814             handle,
815             version,
816             CaEvtDet::ChildCertificatesUpdated {
817                 resource_class_name,
818                 updates,
819             },
820         )
821     }
822 
child_removed(handle: &Handle, version: u64, child: ChildHandle) -> CaEvt823     pub(super) fn child_removed(handle: &Handle, version: u64, child: ChildHandle) -> CaEvt {
824         StoredEvent::new(handle, version, CaEvtDet::ChildRemoved { child })
825     }
826 
child_suspended(handle: &Handle, version: u64, child: ChildHandle) -> CaEvt827     pub(super) fn child_suspended(handle: &Handle, version: u64, child: ChildHandle) -> CaEvt {
828         StoredEvent::new(handle, version, CaEvtDet::ChildSuspended { child })
829     }
830 
child_unsuspended(handle: &Handle, version: u64, child: ChildHandle) -> CaEvt831     pub(super) fn child_unsuspended(handle: &Handle, version: u64, child: ChildHandle) -> CaEvt {
832         StoredEvent::new(handle, version, CaEvtDet::ChildUnsuspended { child })
833     }
834 }
835 
836 impl fmt::Display for CaEvtDet {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result837     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
838         match self {
839             // Being a Trust Anchor
840             CaEvtDet::TrustAnchorMade { ta_cert_details } => write!(
841                 f,
842                 "turn into TA with key (hash) {}",
843                 ta_cert_details.cert().subject_key_identifier()
844             ),
845 
846             // Being a parent Events
847             CaEvtDet::ChildAdded {
848                 child,
849                 id_cert,
850                 resources,
851             } => {
852                 write!(
853                     f,
854                     "added child '{}' with resources '{}, id (hash): {}",
855                     child,
856                     resources,
857                     id_cert.ski_hex()
858                 )
859             }
860             CaEvtDet::ChildCertificateIssued {
861                 child,
862                 resource_class_name,
863                 ki,
864             } => write!(
865                 f,
866                 "issued certificate to child '{}' for class '{}' and pub key '{}'",
867                 child, resource_class_name, ki
868             ),
869             CaEvtDet::ChildCertificatesUpdated {
870                 resource_class_name,
871                 updates,
872             } => {
873                 write!(
874                     f,
875                     "updated child certificates in resource class {}",
876                     resource_class_name
877                 )?;
878                 let issued = updates.issued();
879                 if !issued.is_empty() {
880                     write!(f, " issued keys: ")?;
881                     for iss in issued {
882                         write!(f, " {}", iss.subject_key_identifier())?;
883                     }
884                 }
885                 let revoked = updates.removed();
886                 if !revoked.is_empty() {
887                     write!(f, " revoked keys: ")?;
888                     for rev in revoked {
889                         write!(f, " {}", rev)?;
890                     }
891                 }
892                 let suspended = updates.suspended();
893                 if !suspended.is_empty() {
894                     write!(f, " suspended keys: ")?;
895                     for cert in suspended {
896                         write!(f, " {}", cert.subject_key_identifier())?;
897                     }
898                 }
899                 let unsuspended = updates.unsuspended();
900                 if !unsuspended.is_empty() {
901                     write!(f, " unsuspended keys: ")?;
902                     for cert in unsuspended {
903                         write!(f, " {}", cert.subject_key_identifier())?;
904                     }
905                 }
906 
907                 Ok(())
908             }
909             CaEvtDet::ChildKeyRevoked {
910                 child,
911                 resource_class_name,
912                 ki,
913             } => write!(
914                 f,
915                 "revoked certificate for child '{}' in resource class '{}' with key(hash) '{}'",
916                 child, resource_class_name, ki
917             ),
918             CaEvtDet::ChildUpdatedIdCert { child, id_cert } => {
919                 write!(f, "updated child '{}' id (hash) '{}'", child, id_cert.ski_hex())
920             }
921             CaEvtDet::ChildUpdatedResources { child, resources } => {
922                 write!(f, "updated child '{}' resources to '{}'", child, resources)
923             }
924             CaEvtDet::ChildRemoved { child } => write!(f, "removed child '{}'", child),
925             CaEvtDet::ChildSuspended { child } => write!(f, "suspended child '{}'", child),
926             CaEvtDet::ChildUnsuspended { child } => write!(f, "unsuspended child '{}'", child),
927 
928             // Being a child Events
929             CaEvtDet::IdUpdated { id } => write!(f, "updated RFC8183 id to key '{}'", id.key_hash()),
930             CaEvtDet::ParentAdded { parent, contact } => {
931                 let contact_str = match contact {
932                     ParentCaContact::Ta(_) => "TA proxy",
933                     ParentCaContact::Rfc6492(_) => "RFC6492",
934                 };
935                 write!(f, "added {} parent '{}' ", contact_str, parent)
936             }
937             CaEvtDet::ParentUpdated { parent, contact } => {
938                 let contact_str = match contact {
939                     ParentCaContact::Ta(_) => "TA proxy",
940                     ParentCaContact::Rfc6492(_) => "RFC6492",
941                 };
942                 write!(f, "updated parent '{}' contact to '{}' ", parent, contact_str)
943             }
944             CaEvtDet::ParentRemoved { parent } => write!(f, "removed parent '{}'", parent),
945 
946             CaEvtDet::ResourceClassAdded {
947                 resource_class_name, ..
948             } => write!(f, "added resource class with name '{}'", resource_class_name),
949             CaEvtDet::ResourceClassRemoved {
950                 resource_class_name,
951                 parent,
952                 ..
953             } => write!(
954                 f,
955                 "removed resource class with name '{}' under parent '{}'",
956                 resource_class_name, parent
957             ),
958             CaEvtDet::CertificateRequested {
959                 resource_class_name,
960                 ki,
961                 ..
962             } => write!(
963                 f,
964                 "requested certificate for key (hash) '{}' under resource class '{}'",
965                 ki, resource_class_name
966             ),
967             CaEvtDet::CertificateReceived {
968                 resource_class_name,
969                 ki,
970                 ..
971             } => write!(
972                 f,
973                 "received certificate for key (hash) '{}' under resource class '{}'",
974                 ki, resource_class_name
975             ),
976 
977             // Key life cycle
978             CaEvtDet::KeyRollPendingKeyAdded {
979                 resource_class_name,
980                 pending_key_id,
981             } => {
982                 write!(
983                     f,
984                     "key roll: added pending key '{}' under resource class '{}'",
985                     pending_key_id, resource_class_name
986                 )
987             }
988             CaEvtDet::KeyPendingToNew {
989                 resource_class_name,
990                 new_key,
991             } => write!(
992                 f,
993                 "key roll: moving pending key '{}' to new state under resource class '{}'",
994                 new_key.key_id(),
995                 resource_class_name
996             ),
997             CaEvtDet::KeyPendingToActive {
998                 resource_class_name,
999                 current_key,
1000             } => write!(
1001                 f,
1002                 "activating pending key '{}' under resource class '{}'",
1003                 current_key.key_id(),
1004                 resource_class_name
1005             ),
1006             CaEvtDet::KeyRollActivated {
1007                 resource_class_name,
1008                 revoke_req,
1009             } => write!(
1010                 f,
1011                 "key roll: activated new key, requested revocation of '{}' under resource class '{}'",
1012                 revoke_req.key(),
1013                 resource_class_name
1014             ),
1015             CaEvtDet::KeyRollFinished { resource_class_name } => {
1016                 write!(f, "key roll: finished for resource class '{}'", resource_class_name)
1017             }
1018             CaEvtDet::UnexpectedKeyFound {
1019                 resource_class_name,
1020                 revoke_req,
1021             } => write!(
1022                 f,
1023                 "Found unexpected key in resource class '{}', will try to revoke key id: '{}'",
1024                 resource_class_name,
1025                 revoke_req.key()
1026             ),
1027 
1028             // Route Authorizations
1029             CaEvtDet::RouteAuthorizationAdded { auth } => write!(f, "added ROA: '{}'", auth),
1030             CaEvtDet::RouteAuthorizationRemoved { auth } => write!(f, "removed ROA: '{}'", auth),
1031             CaEvtDet::RoasUpdated {
1032                 resource_class_name,
1033                 updates,
1034             } => {
1035                 write!(f, "updated ROA objects under resource class '{}'", resource_class_name)?;
1036                 if !updates.updated.is_empty() || !updates.aggregate_updated.is_empty() {
1037                     write!(f, " added: ")?;
1038                     for auth in updates.updated.keys() {
1039                         write!(f, "{} ", ObjectName::from(auth))?;
1040                     }
1041                     for agg_key in updates.aggregate_updated.keys() {
1042                         write!(f, "{} ", ObjectName::from(agg_key))?;
1043                     }
1044                 }
1045                 if !updates.removed.is_empty() || !updates.aggregate_removed.is_empty() {
1046                     write!(f, " removed: ")?;
1047                     for auth in updates.removed.keys() {
1048                         write!(f, "{} ", ObjectName::from(auth))?;
1049                     }
1050                     for agg_key in updates.aggregate_removed.keys() {
1051                         write!(f, "{} ", ObjectName::from(agg_key))?;
1052                     }
1053                 }
1054                 Ok(())
1055             }
1056 
1057             // Autonomous System Provider Authorization
1058             CaEvtDet::AspaConfigAdded { aspa_config: addition } => write!(f, "{}", addition),
1059             CaEvtDet::AspaConfigUpdated { customer, update } => {
1060                 write!(f, "updated ASPA config for customer ASN: {} {}", customer, update)
1061             }
1062             CaEvtDet::AspaConfigRemoved { customer } => write!(f, "removed ASPA config for customer ASN: {}", customer),
1063             CaEvtDet::AspaObjectsUpdated {
1064                 resource_class_name,
1065                 updates,
1066             } => {
1067                 write!(f, "updated ASPA objects under resource class '{}'", resource_class_name)?;
1068                 if !updates.updated().is_empty() {
1069                     write!(f, " updated:")?;
1070                     for upd in updates.updated() {
1071                         write!(f, " {}", ObjectName::aspa(upd.customer()))?;
1072                     }
1073                 }
1074                 if !updates.removed().is_empty() {
1075                     write!(f, " removed:")?;
1076                     for rem in updates.removed() {
1077                         write!(f, " {}", ObjectName::aspa(*rem))?;
1078                     }
1079                 }
1080                 Ok(())
1081             }
1082 
1083             // Publishing
1084             CaEvtDet::RepoUpdated { contact } => {
1085                 write!(f, "updated repository to remote server: {}", contact.service_uri())
1086             }
1087 
1088             // Rta
1089             CaEvtDet::RtaPrepared { name, prepared } => {
1090                 write!(f, "Prepared RTA '{}' for resources: {}", name, prepared.resources())
1091             }
1092             CaEvtDet::RtaSigned { name, rta } => {
1093                 write!(f, "Signed RTA '{}' for resources: {}", name, rta.resources())
1094             }
1095         }
1096     }
1097 }
1098