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