1 use chrono::Duration; 2 use serde::{Deserialize, Serialize}; 3 4 use rpki::repository::{ 5 cert::Cert, 6 crypto::KeyIdentifier, 7 x509::{Time, Validity}, 8 }; 9 10 use crate::{ 11 commons::{ 12 api::{ 13 EntitlementClass, Handle, IssuanceRequest, IssuedCert, ParentHandle, RcvdCert, ReplacedObject, RepoInfo, 14 RequestResourceLimit, ResourceClassInfo, ResourceClassName, ResourceSet, RevocationRequest, SuspendedCert, 15 UnsuspendedCert, 16 }, 17 crypto::{CsrInfo, KrillSigner, SignSupport}, 18 error::Error, 19 KrillResult, 20 }, 21 daemon::{ 22 ca::events::RoaUpdates, 23 ca::{ 24 self, ta_handle, AspaObjects, AspaObjectsUpdates, CaEvtDet, CertifiedKey, ChildCertificates, CurrentKey, 25 KeyState, NewKey, OldKey, PendingKey, Roas, Routes, 26 }, 27 config::{Config, IssuanceTimingConfig}, 28 }, 29 }; 30 31 use super::AspaDefinitions; 32 33 //------------ ResourceClass ----------------------------------------------- 34 35 /// A CA may have multiple parents, e.g. two RIRs, and it may not get all its 36 /// resource entitlements in one set, but in a number of so-called "resource 37 /// classes". 38 /// 39 /// Each ResourceClass has a namespace, which can be anything, but for Krill 40 /// is based on the name of the parent ca, and the name of the resource class 41 /// under that parent. 42 /// 43 /// Furthermore a resource class manages the key life cycle, and certificates 44 /// for each key, as well as products that need to be issued by the 'current' 45 /// key for this class. 46 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] 47 pub struct ResourceClass { 48 name: ResourceClassName, 49 name_space: String, 50 51 parent_handle: ParentHandle, 52 parent_rc_name: ResourceClassName, 53 54 roas: Roas, 55 aspas: AspaObjects, 56 certificates: ChildCertificates, 57 58 last_key_change: Time, 59 key_state: KeyState, 60 } 61 62 /// # Creating new instances 63 /// 64 impl ResourceClass { 65 /// Creates a new ResourceClass with a single pending key only. create( name: ResourceClassName, name_space: String, parent_handle: ParentHandle, parent_rc_name: ResourceClassName, pending_key: KeyIdentifier, ) -> Self66 pub fn create( 67 name: ResourceClassName, 68 name_space: String, 69 parent_handle: ParentHandle, 70 parent_rc_name: ResourceClassName, 71 pending_key: KeyIdentifier, 72 ) -> Self { 73 ResourceClass { 74 name, 75 name_space, 76 parent_handle, 77 parent_rc_name, 78 roas: Roas::default(), 79 aspas: AspaObjects::default(), 80 certificates: ChildCertificates::default(), 81 last_key_change: Time::now(), 82 key_state: KeyState::create(pending_key), 83 } 84 } 85 for_ta(parent_rc_name: ResourceClassName, pending_key: KeyIdentifier) -> Self86 pub fn for_ta(parent_rc_name: ResourceClassName, pending_key: KeyIdentifier) -> Self { 87 ResourceClass { 88 name: parent_rc_name.clone(), 89 name_space: parent_rc_name.to_string(), 90 parent_handle: ta_handle(), 91 parent_rc_name, 92 roas: Roas::default(), 93 aspas: AspaObjects::default(), 94 certificates: ChildCertificates::default(), 95 last_key_change: Time::now(), 96 key_state: KeyState::create(pending_key), 97 } 98 } 99 } 100 101 /// # Data Access 102 /// 103 impl ResourceClass { name_space(&self) -> &str104 pub fn name_space(&self) -> &str { 105 &self.name_space 106 } 107 108 /// Returns the name of the parent where we got this RC from. parent_handle(&self) -> &ParentHandle109 pub fn parent_handle(&self) -> &ParentHandle { 110 &self.parent_handle 111 } 112 113 /// Returns the name that the parent uses for this RC. parent_rc_name(&self) -> &ResourceClassName114 pub fn parent_rc_name(&self) -> &ResourceClassName { 115 &self.parent_rc_name 116 } 117 118 /// Adds a request to an existing key for future reference. add_request(&mut self, key_id: KeyIdentifier, req: IssuanceRequest)119 pub fn add_request(&mut self, key_id: KeyIdentifier, req: IssuanceRequest) { 120 self.key_state.add_request(key_id, req); 121 } 122 123 /// Returns the current certificate, if there is any current_certificate(&self) -> Option<&RcvdCert>124 pub fn current_certificate(&self) -> Option<&RcvdCert> { 125 self.current_key().map(|k| k.incoming_cert()) 126 } 127 128 /// Returns the current resources for this resource class current_resources(&self) -> Option<&ResourceSet>129 pub fn current_resources(&self) -> Option<&ResourceSet> { 130 self.current_certificate().map(|c| c.resources()) 131 } 132 133 /// Returns a reference to current key for this RC, if there is any. current_key(&self) -> Option<&CurrentKey>134 pub fn current_key(&self) -> Option<&CurrentKey> { 135 match &self.key_state { 136 KeyState::Active(current) 137 | KeyState::RollPending(_, current) 138 | KeyState::RollNew(_, current) 139 | KeyState::RollOld(current, _) => Some(current), 140 _ => None, 141 } 142 } 143 get_current_key(&self) -> KrillResult<&CurrentKey>144 pub fn get_current_key(&self) -> KrillResult<&CurrentKey> { 145 self.current_key().ok_or(Error::KeyUseNoCurrentKey) 146 } 147 key_roll_possible(&self) -> bool148 pub fn key_roll_possible(&self) -> bool { 149 matches!(&self.key_state, KeyState::Active(_)) 150 } 151 152 /// Gets the new key for a key roll, or returns an error if there is none. get_new_key(&self) -> KrillResult<&NewKey>153 pub fn get_new_key(&self) -> KrillResult<&NewKey> { 154 if let KeyState::RollNew(new_key, _) = &self.key_state { 155 Ok(new_key) 156 } else { 157 Err(Error::KeyUseNoNewKey) 158 } 159 } 160 161 /// Returns a ResourceClassInfo for this, which contains all the 162 /// same data, but which does not have any behavior. as_info(&self) -> ResourceClassInfo163 pub fn as_info(&self) -> ResourceClassInfo { 164 ResourceClassInfo::new( 165 self.name_space.clone(), 166 self.parent_handle.clone(), 167 self.key_state.as_info(), 168 ) 169 } 170 } 171 172 /// # Support repository migrations 173 /// 174 impl ResourceClass { set_old_repo(&mut self, repo: &RepoInfo)175 pub fn set_old_repo(&mut self, repo: &RepoInfo) { 176 self.key_state.set_old_repo_if_in_active_state(repo); 177 } 178 } 179 180 /// # Request certificates 181 /// 182 impl ResourceClass { 183 /// Returns event details for receiving the certificate. update_received_cert( &self, handle: &Handle, rcvd_cert: RcvdCert, all_routes: &Routes, all_aspas: &AspaDefinitions, config: &Config, signer: &KrillSigner, ) -> KrillResult<Vec<CaEvtDet>>184 pub fn update_received_cert( 185 &self, 186 handle: &Handle, 187 rcvd_cert: RcvdCert, 188 all_routes: &Routes, 189 all_aspas: &AspaDefinitions, 190 config: &Config, 191 signer: &KrillSigner, 192 ) -> KrillResult<Vec<CaEvtDet>> { 193 // If this is for a pending key, then we need to promote this key 194 195 let rcvd_cert_ki = rcvd_cert.cert().subject_key_identifier(); 196 197 match &self.key_state { 198 KeyState::Pending(pending) => { 199 if rcvd_cert_ki != pending.key_id() { 200 Err(Error::KeyUseNoMatch(rcvd_cert_ki)) 201 } else { 202 info!( 203 "Received certificate for CA '{}' under RC '{}', with resources: '{}' valid until: '{}'", 204 handle, 205 self.name, 206 rcvd_cert.resources(), 207 rcvd_cert.validity().not_after().to_rfc3339() 208 ); 209 210 let current_key = CertifiedKey::create(rcvd_cert); 211 212 let roa_updates = self.roas.update(all_routes, ¤t_key, config, signer)?; 213 let aspa_updates = self.aspas.update(all_aspas, ¤t_key, config, signer)?; 214 215 let mut events = vec![CaEvtDet::KeyPendingToActive { 216 resource_class_name: self.name.clone(), 217 current_key, 218 }]; 219 220 if roa_updates.contains_changes() { 221 events.push(CaEvtDet::RoasUpdated { 222 resource_class_name: self.name.clone(), 223 updates: roa_updates, 224 }) 225 } 226 227 if aspa_updates.contains_changes() { 228 events.push(CaEvtDet::AspaObjectsUpdated { 229 resource_class_name: self.name.clone(), 230 updates: aspa_updates, 231 }) 232 } 233 234 Ok(events) 235 } 236 } 237 KeyState::Active(current) => { 238 self.update_rcvd_cert_current(handle, current, rcvd_cert, all_routes, all_aspas, config, signer) 239 } 240 KeyState::RollPending(pending, current) => { 241 if rcvd_cert_ki == pending.key_id() { 242 let new_key = CertifiedKey::create(rcvd_cert); 243 Ok(vec![CaEvtDet::KeyPendingToNew { 244 resource_class_name: self.name.clone(), 245 new_key, 246 }]) 247 } else { 248 self.update_rcvd_cert_current(handle, current, rcvd_cert, all_routes, all_aspas, config, signer) 249 } 250 } 251 KeyState::RollNew(new, current) => { 252 if rcvd_cert_ki == new.key_id() { 253 Ok(vec![CaEvtDet::CertificateReceived { 254 resource_class_name: self.name.clone(), 255 ki: rcvd_cert_ki, 256 rcvd_cert, 257 }]) 258 } else { 259 self.update_rcvd_cert_current(handle, current, rcvd_cert, all_routes, all_aspas, config, signer) 260 } 261 } 262 KeyState::RollOld(current, _old) => { 263 // We will never request a new certificate for an old key 264 self.update_rcvd_cert_current(handle, current, rcvd_cert, all_routes, all_aspas, config, signer) 265 } 266 } 267 } 268 269 #[allow(clippy::too_many_arguments)] update_rcvd_cert_current( &self, handle: &Handle, current_key: &CurrentKey, rcvd_cert: RcvdCert, routes: &Routes, aspas: &AspaDefinitions, config: &Config, signer: &KrillSigner, ) -> KrillResult<Vec<CaEvtDet>>270 fn update_rcvd_cert_current( 271 &self, 272 handle: &Handle, 273 current_key: &CurrentKey, 274 rcvd_cert: RcvdCert, 275 routes: &Routes, 276 aspas: &AspaDefinitions, 277 config: &Config, 278 signer: &KrillSigner, 279 ) -> KrillResult<Vec<CaEvtDet>> { 280 let ki = rcvd_cert.cert().subject_key_identifier(); 281 if ki != current_key.key_id() { 282 return Err(ca::Error::KeyUseNoMatch(ki)); 283 } 284 285 let rcvd_resources = rcvd_cert.resources(); 286 287 let mut res = vec![CaEvtDet::CertificateReceived { 288 resource_class_name: self.name.clone(), 289 ki, 290 rcvd_cert: rcvd_cert.clone(), 291 }]; 292 293 let rcvd_resources_diff = rcvd_resources.difference(current_key.incoming_cert().resources()); 294 295 if !rcvd_resources_diff.is_empty() { 296 info!( 297 "Received new certificate under CA '{}' under RC '{}' with changed resources: '{}', valid until: {}", 298 handle, 299 self.name, 300 rcvd_resources_diff, 301 rcvd_cert.validity().not_after().to_rfc3339() 302 ); 303 304 // Prep certified key for updated received certificate 305 let updated_key = CertifiedKey::create(rcvd_cert); 306 307 // Shrink any overclaiming child certificates 308 let updates = self 309 .certificates 310 .shrink_overclaiming(&updated_key, &config.issuance_timing, signer)?; 311 if !updates.is_empty() { 312 res.push(CaEvtDet::ChildCertificatesUpdated { 313 resource_class_name: self.name.clone(), 314 updates, 315 }); 316 } 317 318 // Re-issue ROAs based on updated resources. 319 // Note that route definitions will not have changed in this case, but the decision logic is all the same. 320 { 321 let updates = self.roas.update(routes, &updated_key, config, signer)?; 322 if !updates.is_empty() { 323 res.push(CaEvtDet::RoasUpdated { 324 resource_class_name: self.name.clone(), 325 updates, 326 }); 327 } 328 } 329 330 // Re-issue ASPA objects based on updated resources. 331 // Note that aspa definitions will not have changed in this case, but the decision logic is all the same. 332 { 333 let updates = self.aspas.update(aspas, &updated_key, config, signer)?; 334 if !updates.is_empty() { 335 res.push(CaEvtDet::AspaObjectsUpdated { 336 resource_class_name: self.name.clone(), 337 updates, 338 }) 339 } 340 } 341 } else { 342 info!( 343 "Received new certificate for CA '{}' under RC '{}', valid until: {}", 344 handle, 345 self.name, 346 rcvd_cert.validity().not_after().to_rfc3339() 347 ) 348 } 349 350 Ok(res) 351 } 352 353 /// Request certificates for any key that needs it. 354 /// Also, create revocation events for any unexpected keys to recover from 355 /// issues where the parent believes we have keys that we do not know. This 356 /// can happen in corner cases where re-initialization of Krill as a child 357 /// is done without proper revocation at the parent, or as is the case with 358 /// ARIN - Krill is sometimes told to just drop all resources. make_entitlement_events( &self, handle: &Handle, entitlement: &EntitlementClass, base_repo: &RepoInfo, signer: &KrillSigner, ) -> KrillResult<Vec<CaEvtDet>>359 pub fn make_entitlement_events( 360 &self, 361 handle: &Handle, 362 entitlement: &EntitlementClass, 363 base_repo: &RepoInfo, 364 signer: &KrillSigner, 365 ) -> KrillResult<Vec<CaEvtDet>> { 366 self.key_state.make_entitlement_events( 367 handle, 368 self.name.clone(), 369 entitlement, 370 base_repo, 371 &self.name_space, 372 signer, 373 ) 374 } 375 376 /// Request new certificates for all keys when the base repo changes. make_request_events_new_repo( &self, base_repo: &RepoInfo, signer: &KrillSigner, ) -> KrillResult<Vec<CaEvtDet>>377 pub fn make_request_events_new_repo( 378 &self, 379 base_repo: &RepoInfo, 380 signer: &KrillSigner, 381 ) -> KrillResult<Vec<CaEvtDet>> { 382 self.key_state 383 .request_certs_new_repo(self.name.clone(), base_repo, &self.name_space, signer) 384 } 385 386 /// This function returns all current certificate requests. cert_requests(&self) -> Vec<IssuanceRequest>387 pub fn cert_requests(&self) -> Vec<IssuanceRequest> { 388 self.key_state.cert_requests() 389 } 390 391 /// Returns the revocation request for the old key, if it exists. revoke_request(&self) -> Option<&RevocationRequest>392 pub fn revoke_request(&self) -> Option<&RevocationRequest> { 393 self.key_state.revoke_request() 394 } 395 has_pending_requests(&self) -> bool396 pub fn has_pending_requests(&self) -> bool { 397 !self.cert_requests().is_empty() || self.revoke_request().is_some() 398 } 399 } 400 401 /// # Removing a resource class 402 /// 403 impl ResourceClass { 404 /// Returns revocation requests for all certified keys in this resource class. revoke(&self, signer: &KrillSigner) -> KrillResult<Vec<RevocationRequest>>405 pub fn revoke(&self, signer: &KrillSigner) -> KrillResult<Vec<RevocationRequest>> { 406 self.key_state.revoke(self.parent_rc_name.clone(), signer) 407 } 408 } 409 410 /// # Key Life Cycle and Receiving Certificates 411 /// 412 impl ResourceClass { 413 /// This function marks a certificate as received. received_cert(&mut self, key_id: KeyIdentifier, cert: RcvdCert)414 pub fn received_cert(&mut self, key_id: KeyIdentifier, cert: RcvdCert) { 415 // if there is a pending key, then we need to do some promotions.. 416 match &mut self.key_state { 417 KeyState::Pending(_pending) => panic!("Would have received KeyPendingToActive event"), 418 KeyState::Active(current) => { 419 current.set_incoming_cert(cert); 420 } 421 KeyState::RollPending(_pending, current) => { 422 current.set_incoming_cert(cert); 423 } 424 KeyState::RollNew(new, current) => { 425 if new.key_id() == &key_id { 426 new.set_incoming_cert(cert); 427 } else { 428 current.set_incoming_cert(cert); 429 } 430 } 431 KeyState::RollOld(current, old) => { 432 if current.key_id() == &key_id { 433 current.set_incoming_cert(cert); 434 } else { 435 old.set_incoming_cert(cert); 436 } 437 } 438 } 439 } 440 441 /// Adds a pending key. pending_key_id_added(&mut self, key_id: KeyIdentifier)442 pub fn pending_key_id_added(&mut self, key_id: KeyIdentifier) { 443 match &self.key_state { 444 KeyState::Active(current) => { 445 let pending = PendingKey::new(key_id); 446 self.key_state = KeyState::RollPending(pending, current.clone()) 447 } 448 _ => panic!("Should never create event to add key when roll in progress"), 449 } 450 } 451 452 /// Moves a pending key to new pending_key_to_new(&mut self, new: CertifiedKey)453 pub fn pending_key_to_new(&mut self, new: CertifiedKey) { 454 match &self.key_state { 455 KeyState::RollPending(_pending, current) => { 456 self.key_state = KeyState::RollNew(new, current.clone()); 457 } 458 _ => panic!("Cannot move pending to new, if state is not roll pending"), 459 } 460 } 461 462 /// Moves a pending key to current pending_key_to_active(&mut self, new: CertifiedKey)463 pub fn pending_key_to_active(&mut self, new: CertifiedKey) { 464 match &self.key_state { 465 KeyState::Pending(_pending) => { 466 self.key_state = KeyState::Active(new); 467 } 468 _ => panic!("Cannot move pending to active, if state is not pending"), 469 } 470 } 471 472 /// Activates the new key new_key_activated(&mut self, revoke_req: RevocationRequest)473 pub fn new_key_activated(&mut self, revoke_req: RevocationRequest) { 474 match &self.key_state { 475 KeyState::RollNew(new, current) => { 476 let old_key = OldKey::new(current.clone(), revoke_req); 477 self.key_state = KeyState::RollOld(new.clone(), old_key); 478 } 479 _ => panic!("Should never create event to activate key when no roll in progress"), 480 } 481 } 482 483 /// Removes the old key, we return the to the state where there is one active key. old_key_removed(&mut self)484 pub fn old_key_removed(&mut self) { 485 match &self.key_state { 486 KeyState::RollOld(current, _old) => { 487 self.key_state = KeyState::Active(current.clone()); 488 } 489 _ => panic!("Should never create event to remove old key, when there is none"), 490 } 491 } 492 493 /// Initiate a key roll keyroll_initiate( &self, base_repo: &RepoInfo, duration: Duration, signer: &KrillSigner, ) -> KrillResult<Vec<CaEvtDet>>494 pub fn keyroll_initiate( 495 &self, 496 base_repo: &RepoInfo, 497 duration: Duration, 498 signer: &KrillSigner, 499 ) -> KrillResult<Vec<CaEvtDet>> { 500 if duration > Duration::seconds(0) && self.last_key_change + duration > Time::now() { 501 return Ok(vec![]); 502 } 503 504 self.key_state.keyroll_initiate( 505 self.name.clone(), 506 self.parent_rc_name.clone(), 507 base_repo, 508 &self.name_space, 509 signer, 510 ) 511 } 512 513 /// Activate a new key, if it's been longer than the staging period. keyroll_activate( &self, staging_time: Duration, issuance_timing: &IssuanceTimingConfig, signer: &KrillSigner, ) -> KrillResult<Vec<CaEvtDet>>514 pub fn keyroll_activate( 515 &self, 516 staging_time: Duration, 517 issuance_timing: &IssuanceTimingConfig, 518 signer: &KrillSigner, 519 ) -> KrillResult<Vec<CaEvtDet>> { 520 if let Some(new_key) = self.key_state.new_key() { 521 if staging_time > Duration::seconds(0) && self.last_key_change + staging_time > Time::now() { 522 Ok(vec![]) 523 } else { 524 let key_activated = 525 self.key_state 526 .keyroll_activate(self.name.clone(), self.parent_rc_name.clone(), signer)?; 527 528 let mut events = vec![key_activated]; 529 530 let roa_updates = self.roas.renew(true, new_key, issuance_timing, signer)?; 531 if !roa_updates.is_empty() { 532 let roas_updated = CaEvtDet::RoasUpdated { 533 resource_class_name: self.name.clone(), 534 updates: roa_updates, 535 }; 536 events.push(roas_updated); 537 } 538 539 let aspa_updates = self.aspas.renew(new_key, None, issuance_timing, signer)?; 540 if !aspa_updates.is_empty() { 541 let aspas_updated = CaEvtDet::AspaObjectsUpdated { 542 resource_class_name: self.name.clone(), 543 updates: aspa_updates, 544 }; 545 events.push(aspas_updated); 546 } 547 548 let cert_updates = self.certificates.activate_key(new_key, issuance_timing, signer)?; 549 if !cert_updates.is_empty() { 550 let certs_updated = CaEvtDet::ChildCertificatesUpdated { 551 resource_class_name: self.name.clone(), 552 updates: cert_updates, 553 }; 554 events.push(certs_updated); 555 } 556 557 Ok(events) 558 } 559 } else { 560 Ok(vec![]) 561 } 562 } 563 564 /// Finish a key roll, withdraw the old key keyroll_finish(&self) -> KrillResult<CaEvtDet>565 pub fn keyroll_finish(&self) -> KrillResult<CaEvtDet> { 566 match &self.key_state { 567 KeyState::RollOld(_current, _old) => Ok(CaEvtDet::KeyRollFinished { 568 resource_class_name: self.name.clone(), 569 }), 570 _ => Err(Error::KeyUseNoOldKey), 571 } 572 } 573 } 574 575 /// # Issuing certificates 576 /// 577 impl ResourceClass { 578 /// Makes a single CA certificate and wraps it in an issuance response. 579 /// 580 /// Will use the intersection of the requested child resources, and the 581 /// resources actually held by the this resource class. An error will be 582 /// returned if a ResourceRequestLimit was used that includes resources 583 /// that are not in this intersection. 584 /// 585 /// Note that this certificate still needs to be added to this RC by 586 /// calling the update_certs function. issue_cert( &self, csr: CsrInfo, child_resources: &ResourceSet, limit: RequestResourceLimit, issuance_timing: &IssuanceTimingConfig, signer: &KrillSigner, ) -> KrillResult<IssuedCert>587 pub fn issue_cert( 588 &self, 589 csr: CsrInfo, 590 child_resources: &ResourceSet, 591 limit: RequestResourceLimit, 592 issuance_timing: &IssuanceTimingConfig, 593 signer: &KrillSigner, 594 ) -> KrillResult<IssuedCert> { 595 let signing_key = self.get_current_key()?; 596 let parent_resources = signing_key.incoming_cert().resources(); 597 let resources = parent_resources.intersection(child_resources); 598 let replaces = self.certificates.get_issued(&csr.key_id()).map(ReplacedObject::from); 599 600 let issued = SignSupport::make_issued_cert( 601 csr, 602 &resources, 603 limit, 604 replaces, 605 signing_key, 606 issuance_timing.timing_child_certificate_valid_weeks, 607 signer, 608 )?; 609 610 Ok(issued) 611 } 612 613 /// Stores an [IssuedCert](krill_commons.api.ca.IssuedCert) certificate_issued(&mut self, issued: IssuedCert)614 pub fn certificate_issued(&mut self, issued: IssuedCert) { 615 self.certificates.certificate_issued(issued); 616 } 617 certificate_unsuspended(&mut self, unsuspended: UnsuspendedCert)618 pub fn certificate_unsuspended(&mut self, unsuspended: UnsuspendedCert) { 619 self.certificates.certificate_unsuspended(unsuspended); 620 } 621 certificate_suspended(&mut self, suspended: SuspendedCert)622 pub fn certificate_suspended(&mut self, suspended: SuspendedCert) { 623 self.certificates.certificate_suspended(suspended); 624 } 625 626 /// Returns an issued certificate for a key, if it exists issued(&self, ki: &KeyIdentifier) -> Option<&IssuedCert>627 pub fn issued(&self, ki: &KeyIdentifier) -> Option<&IssuedCert> { 628 self.certificates.get_issued(ki) 629 } 630 631 /// Returns a suspended certificate for a key, if it exists suspended(&self, ki: &KeyIdentifier) -> Option<&SuspendedCert>632 pub fn suspended(&self, ki: &KeyIdentifier) -> Option<&SuspendedCert> { 633 self.certificates.get_suspended(ki) 634 } 635 636 /// Removes a revoked key. key_revoked(&mut self, key: &KeyIdentifier)637 pub fn key_revoked(&mut self, key: &KeyIdentifier) { 638 self.certificates.key_revoked(key); 639 } 640 } 641 642 /// # ROAs 643 /// 644 impl ResourceClass { 645 /// Renew all ROAs under the current for which the not-after time closer 646 /// than the given number of weeks renew_roas( &self, force: bool, issuance_timing: &IssuanceTimingConfig, signer: &KrillSigner, ) -> KrillResult<RoaUpdates>647 pub fn renew_roas( 648 &self, 649 force: bool, 650 issuance_timing: &IssuanceTimingConfig, 651 signer: &KrillSigner, 652 ) -> KrillResult<RoaUpdates> { 653 let key = self.get_current_key()?; 654 self.roas.renew(force, key, issuance_timing, signer) 655 } 656 657 /// Publish all ROAs under the new key active_key_roas( &self, issuance_timing: &IssuanceTimingConfig, signer: &KrillSigner, ) -> KrillResult<RoaUpdates>658 pub fn active_key_roas( 659 &self, 660 issuance_timing: &IssuanceTimingConfig, 661 signer: &KrillSigner, 662 ) -> KrillResult<RoaUpdates> { 663 let key = self.get_new_key()?; 664 self.roas.renew(true, key, issuance_timing, signer) 665 } 666 667 /// Updates the ROAs in accordance with the current authorizations update_roas(&self, routes: &Routes, config: &Config, signer: &KrillSigner) -> KrillResult<RoaUpdates>668 pub fn update_roas(&self, routes: &Routes, config: &Config, signer: &KrillSigner) -> KrillResult<RoaUpdates> { 669 let key = self.get_current_key()?; 670 let resources = key.incoming_cert().resources(); 671 let routes = routes.filter(resources); 672 self.roas.update(&routes, key, config, signer) 673 } 674 675 /// Marks the ROAs as updated from a RoaUpdated event. roas_updated(&mut self, updates: RoaUpdates)676 pub fn roas_updated(&mut self, updates: RoaUpdates) { 677 self.roas.updated(updates); 678 } 679 } 680 681 /// # Autonomous System Provider Authorization 682 /// 683 impl ResourceClass { 684 /// Renew all ASPA objects under the current for which the not-after time 685 /// is closer than the given number of weeks renew_aspas( &self, issuance_timing: &IssuanceTimingConfig, signer: &KrillSigner, ) -> KrillResult<AspaObjectsUpdates>686 pub fn renew_aspas( 687 &self, 688 issuance_timing: &IssuanceTimingConfig, 689 signer: &KrillSigner, 690 ) -> KrillResult<AspaObjectsUpdates> { 691 let key = self.get_current_key()?; 692 let renew_threshold = Some(Time::now() + Duration::weeks(issuance_timing.timing_aspa_reissue_weeks_before)); 693 self.aspas.renew(key, renew_threshold, issuance_timing, signer) 694 } 695 696 /// Updates the ASPA objects in accordance with the supplied definitions update_aspas( &self, all_aspas: &AspaDefinitions, config: &Config, signer: &KrillSigner, ) -> KrillResult<AspaObjectsUpdates>697 pub fn update_aspas( 698 &self, 699 all_aspas: &AspaDefinitions, 700 config: &Config, 701 signer: &KrillSigner, 702 ) -> KrillResult<AspaObjectsUpdates> { 703 let key = self.get_current_key()?; 704 self.aspas.update(all_aspas, key, config, signer) 705 } 706 707 /// Apply ASPA object changes from events aspa_objects_updated(&mut self, updates: AspaObjectsUpdates)708 pub fn aspa_objects_updated(&mut self, updates: AspaObjectsUpdates) { 709 self.aspas.updated(updates) 710 } 711 } 712 713 /// # Resource Tagged Attestations (RTA) 714 /// 715 impl ResourceClass { 716 /// Create an EE certificate to be used on an RTA, 717 /// returns None if there is no overlap in resources 718 /// between the desired resources on the RTA and this 719 /// ResourceClass current resources. create_rta_ee( &self, resources: &ResourceSet, validity: Validity, key: KeyIdentifier, signer: &KrillSigner, ) -> KrillResult<Cert>720 pub fn create_rta_ee( 721 &self, 722 resources: &ResourceSet, 723 validity: Validity, 724 key: KeyIdentifier, 725 signer: &KrillSigner, 726 ) -> KrillResult<Cert> { 727 let current = self 728 .current_key() 729 .ok_or_else(|| Error::custom("No current key to sign RTA with"))?; 730 731 if !current.incoming_cert().resources().contains(resources) { 732 return Err(Error::custom("Resources for RTA not held")); 733 } 734 735 let pub_key = signer.get_key_info(&key).map_err(Error::signer)?; 736 let ee = SignSupport::make_rta_ee_cert(resources, current, validity, pub_key, signer)?; 737 738 Ok(ee) 739 } 740 } 741