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, &current_key, config, signer)?;
213                     let aspa_updates = self.aspas.update(all_aspas, &current_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