1 //! Resource certificates.
2 //!
3 //! The certificates used in RPKI are called _resource certificates._ They
4 //! are defined in [RFC 6487] as a profile on regular Internet PKI
5 //! certificates defined in [RFC 5280]. While they use the format defined
6 //! for X.509 certificates, the allowed values for various fields are limited
7 //! making the overall structure more simple and predictable.
8 //!
9 //! This module implements raw resource certificates in the type [`Cert`] and
10 //! validated certificates in the type [`ResourceCert`]. The latter type is
11 //! used for issuer certificates when validating other certificates.
12 //!
13 //! In addition, there are several types for the components of a certificate.
14 //!
15 //! [`Cert`]: struct.Cert.html
16 //! [`ResourceCert`]: struct.ResourceCert.html
17 //! [RFC 5280]: https://tools.ietf.org/html/rfc5280
18 //! [RFC 6487]: https://tools.ietf.org/html/rfc5487
19 
20 use std::{borrow, ops};
21 use std::iter::FromIterator;
22 use std::sync::Arc;
23 use bcder::{decode, encode};
24 use bcder::xerr;
25 use bcder::encode::PrimitiveContent;
26 use bcder::{
27     BitString, Captured, ConstOid, Ia5String, Mode, OctetString, Oid, Tag
28 };
29 use bytes::Bytes;
30 use crate::uri;
31 use super::crypto::{
32     KeyIdentifier, PublicKey, SignatureAlgorithm, Signer, SigningError
33 };
34 use super::oid;
35 use super::resources::{
36     AsBlock, AsBlocks, AsBlocksBuilder, AsResources, AsResourcesBuilder,
37     IpBlock, IpBlocks, IpBlocksBuilder, IpResources, IpResourcesBuilder
38 };
39 use super::tal::TalInfo;
40 use super::x509::{
41     Name, SignedData, Serial, Time, Validity, ValidationError,
42     encode_extension, update_first, update_once
43 };
44 
45 
46 //------------ Cert ----------------------------------------------------------
47 
48 /// A raw resource certificate.
49 ///
50 /// A value of this type represents a resource certificate. It can be one of
51 /// three different variants.
52 ///
53 /// A _CA certificate_ appears in its own file in the repository. Its main
54 /// use is to sign other certificates.
55 ///
56 /// An _EE certificate_ is used to sign other objects in the repository, such
57 /// as manifests or ROAs and is included in the file of these objects. In
58 /// RPKI, EE certificates are used only once.  Whenever a new object is
59 /// created, a new EE certificate is created, signed by its CA, used to sign
60 /// the object, and then the private key is thrown away.
61 ///
62 /// Finally, _TA certificates_ are the installed trust anchors. These are
63 /// self-signed.
64 ///
65 /// If a certificate is stored in a file, you can use the [`decode`] function
66 /// to parse the entire file. If the certificate is part of some other
67 /// structure, the [`take_from`] and [`from_constructed`] functions can be
68 /// used during parsing of that structure.
69 ///
70 /// Once parsing succeeded, the three methods [`validate_ca`],
71 /// [`validate_ee`], and [`validate_ta`] can be used to validate the
72 /// certificate and turn it into a [`ResourceCert`] so it can be used for
73 /// further processing. In addition, various methods exist to access
74 /// information contained in the certificate.
75 ///
76 /// [`ResourceCert`]: struct.ResourceCert.html
77 /// [`decode`]: #method.decode
78 /// [`take_from`]: #method.take_from
79 /// [`from_constructed`]: #method.from_constructed
80 /// [`validate_ca`]: #method.validate_ca
81 /// [`validate_ee`]: #method.validate_ee
82 /// [`validate_ta`]: #method.validate_ta
83 #[derive(Clone, Debug)]
84 pub struct Cert {
85     /// The outer structure of the certificate.
86     signed_data: SignedData,
87 
88     /// The actual data of the certificate.
89     tbs: TbsCert,
90 }
91 
92 
93 /// # Decoding and Encoding
94 ///
95 impl Cert {
96     /// Decodes a source as a certificate.
decode<S: decode::Source>(source: S) -> Result<Self, S::Err>97     pub fn decode<S: decode::Source>(source: S) -> Result<Self, S::Err> {
98         Mode::Der.decode(source, Self::take_from)
99     }
100 
101     /// Takes an encoded certificate from the beginning of a value.
102     ///
103     /// This function assumes that the certificate is encoded in the next
104     /// constructed value in `cons` tagged as a sequence.
take_from<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<Self, S::Err>105     pub fn take_from<S: decode::Source>(
106         cons: &mut decode::Constructed<S>
107     ) -> Result<Self, S::Err> {
108         cons.take_sequence(Self::from_constructed)
109     }
110 
111     /// Takes an optional certificate from the beginning of a value.
take_opt_from<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<Option<Self>, S::Err>112     pub fn take_opt_from<S: decode::Source>(
113         cons: &mut decode::Constructed<S>
114     ) -> Result<Option<Self>, S::Err> {
115         cons.take_opt_sequence(Self::from_constructed)
116     }
117 
118     /// Parses the content of a Certificate sequence.
from_constructed<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<Self, S::Err>119     pub fn from_constructed<S: decode::Source>(
120         cons: &mut decode::Constructed<S>
121     ) -> Result<Self, S::Err> {
122         let signed_data = SignedData::from_constructed(cons)?;
123         let tbs = signed_data.data().clone().decode(
124             TbsCert::from_constructed
125         )?;
126         Ok(Self { signed_data, tbs })
127     }
128 
129     /// Returns a value encoder for a reference to the certificate.
encode_ref(&self) -> impl encode::Values + '_130     pub fn encode_ref(&self) -> impl encode::Values + '_ {
131         self.signed_data.encode_ref()
132     }
133 
134     /// Returns a captured encoding of the certificate.
to_captured(&self) -> Captured135     pub fn to_captured(&self) -> Captured {
136         Captured::from_values(Mode::Der, self.encode_ref())
137     }
138 }
139 
140 
141 /// # Validation
142 ///
143 /// When validating a certificate, two properties are checked: whether the
144 /// certificate’s structure and content comply with the specification for
145 /// resource certificates laid out in [RFC 6487] and whether the certificate
146 /// has been correctly issued by its CA.
147 ///
148 /// In some cases it is useful to perform these two steps separately.
149 /// Therefore, methods are available both for each step and for doing both
150 /// steps at once. Since we need to name these consistently, we devised the
151 /// following convention:
152 ///
153 /// The first step that validates compliance with the specification is called
154 /// _inspection._ Methods are available to inspect different kinds of
155 /// certificates. They all have the verb _inspect_ in their name. Only the
156 /// certificate itself is necessary to perform inspection.
157 ///
158 /// The second step checking whether the certificate was correctly issued is
159 /// called _verification._ Methods are available to verify different kinds of
160 /// certificates. They all have the verb _verify_ in their name and, in
161 /// most cases, require access to the issuer certificate.
162 ///
163 /// In addition, methods are available to perform both steps at once for
164 /// different kinds of certificates. These all have _validate_ in their name.
165 impl Cert {
166     //--- Validation
167 
168     /// Validates the certificate as a trust anchor.
169     ///
170     /// This validates that the certificate “is a current, self-signed RPKI
171     /// CA certificate that conforms to the profile as specified in
172     /// RFC6487” (RFC7730, section 3, step 2).
validate_ta( self, tal: Arc<TalInfo>, strict: bool ) -> Result<ResourceCert, ValidationError>173     pub fn validate_ta(
174         self,
175         tal: Arc<TalInfo>,
176         strict: bool
177     ) -> Result<ResourceCert, ValidationError> {
178         self.validate_ta_at(tal, strict, Time::now())
179     }
180 
validate_ta_at( self, tal: Arc<TalInfo>, strict: bool, now: Time, ) -> Result<ResourceCert, ValidationError>181     pub fn validate_ta_at(
182         self,
183         tal: Arc<TalInfo>,
184         strict: bool,
185         now: Time,
186     ) -> Result<ResourceCert, ValidationError> {
187         self.inspect_ta_at(strict, now)?;
188         self.verify_ta(tal, strict)
189     }
190 
191     /// Validates the certificate as a CA certificate.
192     ///
193     /// For validation to succeed, the certificate needs to have been signed
194     /// by the provided `issuer` certificate.
195     ///
196     /// Note that this does _not_ check the CRL.
validate_ca( self, issuer: &ResourceCert, strict: bool ) -> Result<ResourceCert, ValidationError>197     pub fn validate_ca(
198         self,
199         issuer: &ResourceCert,
200         strict: bool
201     ) -> Result<ResourceCert, ValidationError> {
202         self.validate_ca_at(issuer, strict, Time::now())
203     }
204 
validate_ca_at( self, issuer: &ResourceCert, strict: bool, now: Time, ) -> Result<ResourceCert, ValidationError>205     pub fn validate_ca_at(
206         self,
207         issuer: &ResourceCert,
208         strict: bool,
209         now: Time,
210     ) -> Result<ResourceCert, ValidationError> {
211         self.inspect_ca_at(strict, now)?;
212         self.verify_ca(issuer, strict)
213     }
214 
215     /// Validates the certificate as an EE RPKI-internal certificate.
216     ///
217     /// For validation to succeed, the certificate needs to have been signed
218     /// by the provided `issuer` certificate.
219     ///
220     /// Note that this does _not_ check the CRL.
221     ///
222     /// Note further that this method should not be used for router
223     /// certificates. Use `validate_router` for that.
validate_ee( self, issuer: &ResourceCert, strict: bool ) -> Result<ResourceCert, ValidationError>224     pub fn validate_ee(
225         self,
226         issuer: &ResourceCert,
227         strict: bool
228     ) -> Result<ResourceCert, ValidationError>  {
229         self.validate_ee_at(issuer, strict, Time::now())
230     }
231 
validate_ee_at( self, issuer: &ResourceCert, strict: bool, now: Time, ) -> Result<ResourceCert, ValidationError>232     pub fn validate_ee_at(
233         self,
234         issuer: &ResourceCert,
235         strict: bool,
236         now: Time,
237     ) -> Result<ResourceCert, ValidationError>  {
238         self.inspect_ee_at(strict, now)?;
239         self.verify_ee(issuer, strict)
240     }
241 
validate_detached_ee( self, issuer: &ResourceCert, strict: bool ) -> Result<ResourceCert, ValidationError>242     pub fn validate_detached_ee(
243         self,
244         issuer: &ResourceCert,
245         strict: bool
246     ) -> Result<ResourceCert, ValidationError>  {
247         self.validate_detached_ee_at(issuer, strict, Time::now())
248     }
249 
validate_detached_ee_at( self, issuer: &ResourceCert, strict: bool, now: Time, ) -> Result<ResourceCert, ValidationError>250     pub fn validate_detached_ee_at(
251         self,
252         issuer: &ResourceCert,
253         strict: bool,
254         now: Time,
255     ) -> Result<ResourceCert, ValidationError>  {
256         self.inspect_detached_ee_at(strict, now)?;
257         self.verify_ee(issuer, strict)
258     }
259 
validate_router( &self, issuer: &ResourceCert, strict: bool ) -> Result<(), ValidationError>260     pub fn validate_router(
261         &self,
262         issuer: &ResourceCert,
263         strict: bool
264     ) -> Result<(), ValidationError> {
265         self.validate_router_at(issuer, strict, Time::now())
266     }
267 
validate_router_at( &self, issuer: &ResourceCert, strict: bool, now: Time, ) -> Result<(), ValidationError>268     pub fn validate_router_at(
269         &self,
270         issuer: &ResourceCert,
271         strict: bool,
272         now: Time,
273     ) -> Result<(), ValidationError> {
274         self.inspect_router_at(strict, now)?;
275         self.verify_router(issuer, strict)
276     }
277 
278 
279     //--- Inspection
280 
inspect_ta(&self, strict: bool) -> Result<(), ValidationError>281     pub fn inspect_ta(&self, strict: bool) -> Result<(), ValidationError> {
282         self.inspect_ta_at(strict, Time::now())
283     }
284 
inspect_ta_at( &self, strict: bool, now: Time ) -> Result<(), ValidationError>285     pub fn inspect_ta_at(
286         &self,
287         strict: bool,
288         now: Time
289     ) -> Result<(), ValidationError> {
290         self.inspect_basics(strict, now)?;
291         self.inspect_ca_basics(strict)?;
292 
293         // 4.8.3. Authority Key Identifier. May be present, if so, must be
294         // equal to the subject key identifier.
295         if let Some(ref aki) = self.authority_key_identifier {
296             if *aki != self.subject_key_identifier {
297                 return Err(ValidationError);
298             }
299         }
300 
301         // 4.8.6. CRL Distribution Points. There mustn’t be one.
302         if self.crl_uri.is_some() {
303             return Err(ValidationError)
304         }
305 
306         // 4.8.7. Authority Information Access. Must not be present.
307         if self.ca_issuer.is_some() {
308             return Err(ValidationError)
309         }
310 
311         // 4.8.10. IP Resources.
312         // 4.8.11. AS Resources.
313         //
314         // Are checked as part of verification.
315 
316         Ok(())
317     }
318 
inspect_ca(&self, strict: bool) -> Result<(), ValidationError>319     pub fn inspect_ca(&self, strict: bool) -> Result<(), ValidationError> {
320         self.inspect_ca_at(strict, Time::now())
321     }
322 
inspect_ca_at( &self, strict: bool, now: Time ) -> Result<(), ValidationError>323     pub fn inspect_ca_at(
324         &self, strict: bool, now: Time
325     ) -> Result<(), ValidationError> {
326         self.inspect_basics(strict, now)?;
327         self.inspect_ca_basics(strict)?;
328         self.inspect_issued(strict)
329     }
330 
inspect_ee(&self, strict: bool) -> Result<(), ValidationError>331     pub fn inspect_ee(&self, strict: bool) -> Result<(), ValidationError> {
332         self.inspect_ee_at(strict, Time::now())
333     }
334 
inspect_ee_at( &self, strict: bool, now: Time ) -> Result<(), ValidationError>335     pub fn inspect_ee_at(
336         &self, strict: bool, now: Time
337     ) -> Result<(), ValidationError> {
338         self.inspect_basics(strict, now)?;
339         self.inspect_issued(strict)?;
340 
341         // 4.8.1. Basic Constraints: Must not be present.
342         if self.basic_ca.is_some(){
343             xerr!(return Err(ValidationError))
344         }
345 
346         // 4.8.4. Key Usage. Bits for CA or not CA have been checked during
347         // parsing already.
348         if self.key_usage != KeyUsage::Ee {
349             xerr!(return Err(ValidationError))
350         }
351 
352         // 4.8.8.  Subject Information Access. We need the signed object
353         // but not the other ones.
354         if self.ca_repository.is_some() || self.rpki_manifest.is_some()
355             || self.signed_object.is_none()
356         {
357             xerr!(return Err(ValidationError))
358         }
359 
360         Ok(())
361     }
362 
inspect_detached_ee( &self, strict: bool ) -> Result<(), ValidationError>363     pub fn inspect_detached_ee(
364         &self, strict: bool
365     ) -> Result<(), ValidationError> {
366         self.inspect_detached_ee_at(strict, Time::now())
367     }
368 
inspect_detached_ee_at( &self, strict: bool, now: Time ) -> Result<(), ValidationError>369     pub fn inspect_detached_ee_at(
370         &self, strict: bool, now: Time
371     ) -> Result<(), ValidationError> {
372         self.inspect_basics(strict, now)?;
373         self.inspect_issued(strict)?;
374 
375         // 4.8.1. Basic Constraints: Must not be present.
376         if self.basic_ca.is_some(){
377             xerr!(return Err(ValidationError))
378         }
379 
380         // 4.8.4. Key Usage. Bits for CA or not CA have been checked during
381         // parsing already.
382         if self.key_usage != KeyUsage::Ee {
383             xerr!(return Err(ValidationError))
384         }
385 
386         // 4.8.8.  Subject Information Access. We allow the signed object one
387         // but not the other ones.
388         if self.ca_repository.is_some() || self.rpki_manifest.is_some() {
389             xerr!(return Err(ValidationError))
390         }
391 
392         Ok(())
393     }
394 
inspect_router( &self, strict: bool ) -> Result<(), ValidationError>395     pub fn inspect_router(
396         &self, strict: bool
397     ) -> Result<(), ValidationError> {
398         self.inspect_router_at(strict, Time::now())
399     }
400 
inspect_router_at( &self, strict: bool, now: Time ) -> Result<(), ValidationError>401     pub fn inspect_router_at(
402         &self, strict: bool, now: Time
403     ) -> Result<(), ValidationError> {
404         // 4.2 Serial Number: must be unique over the CA. We cannot check
405         // here, and -- XXX --- probably don’t care?
406 
407         // 4.3 Signature Algorithm: limited to those in RFC 6485. Already
408         // checked in parsing.
409         //
410         // However, RFC 5280 demands that the two mentions of the signature
411         // algorithm are the same. So we do that here.
412         if self.signature != self.signed_data.signature().algorithm() {
413             return Err(ValidationError)
414         }
415 
416         // 4.4 Issuer: must have certain format.
417         Name::validate_rpki(&self.issuer, strict)?;
418 
419         // 4.5 Subject: same as 4.4.
420         Name::validate_router(&self.subject, strict)?;
421 
422         // 4.6 Validity. Check according to RFC 5280.
423         self.validity.validate_at(now)?;
424 
425         // 4.7 Subject Public Key Info: limited algorithms.
426         if !self.subject_public_key_info().allow_router_cert() {
427             xerr!(return Err(ValidationError))
428         }
429 
430         // 4.8.1. Basic Constraints. Must not be present.
431         if self.basic_ca.is_some(){
432             xerr!(return Err(ValidationError))
433         }
434 
435         // 4.8.2. Subject Key Identifier. Must be the SHA-1 hash of the octets
436         // of the subjectPublicKey.
437         if self.subject_key_identifier() !=
438                              self.subject_public_key_info().key_identifier() {
439             return Err(ValidationError)
440         }
441 
442         // 4.8.3. Authority Key Identifier. Will be checked during
443         // verification later.
444 
445         // 4.8.4. Key Usage. Must be EE.
446         if self.key_usage != KeyUsage::Ee {
447             xerr!(return Err(ValidationError))
448         }
449 
450         // 4.8.5. Extended Key Usage.
451         //
452         // Must be present and contain at least the kp-bgpsec-router OID.
453         self.inspect_router_eku(strict)?;
454 
455         // 4.8.6. CRL Distribution Points. There must be one.
456         if self.crl_uri().is_none() {
457             return Err(ValidationError)
458         }
459 
460         // 4.8.7. Authority Information Access. Differs between TA and other
461         // certificates.
462 
463         // 4.8.8.  Subject Information Access. There must be none.
464         if self.ca_repository().is_some() || self.rpki_manifest().is_some()
465             || self.signed_object().is_some() || self.rpki_notify().is_some()
466         {
467             return Err(ValidationError)
468         }
469 
470         // 4.8.9.  Certificate Policies. XXX I think this can be ignored.
471         // At least for now.
472 
473         // 4.8.10.  IP Resources.  Must not be present.
474         if self.v4_resources().is_present() || self.v6_resources().is_present()
475         {
476             return Err(ValidationError)
477         }
478 
479         // 4.8.11.  AS Resources. Differs between trust anchor and issued
480         // certificates.
481         if !self.as_resources().is_present()
482             || self.as_resources().is_inherited()
483         {
484             return Err(ValidationError)
485         }
486 
487         Ok(())
488     }
489 
490     //--- Verification
491 
verify_ta( self, tal: Arc<TalInfo>, _strict: bool ) -> Result<ResourceCert, ValidationError>492     pub fn verify_ta(
493         self, tal: Arc<TalInfo>, _strict: bool
494     ) -> Result<ResourceCert, ValidationError> {
495         // 4.8.10. IP Resources. If present, mustn’t be "inherit".
496         let v4_resources = IpBlocks::from_resources(
497             self.v4_resources.clone()
498         )?;
499         let v6_resources = IpBlocks::from_resources(
500             self.v6_resources.clone()
501         )?;
502 
503         // 4.8.11.  AS Resources. If present, mustn’t be "inherit". That
504         // IP resources (logical) or AS resources are present has already
505         // been checked during parsing.
506         let as_resources = AsBlocks::from_resources(
507             self.as_resources.clone()
508         )?;
509 
510         self.signed_data.verify_signature(
511             &self.subject_public_key_info
512         )?;
513 
514         Ok(ResourceCert {
515             cert: self,
516             v4_resources,
517             v6_resources,
518             as_resources,
519             tal
520         })
521     }
522 
verify_ta_ref( &self, _strict: bool ) -> Result<(), ValidationError>523     pub fn verify_ta_ref(
524         &self, _strict: bool
525     ) -> Result<(), ValidationError> {
526         // 4.8.10. IP Resources. If present, mustn’t be "inherit".
527         if self.v4_resources.is_inherited() {
528             return Err(ValidationError)
529         }
530         if self.v6_resources.is_inherited() {
531             return Err(ValidationError)
532         }
533 
534         // 4.8.11.  AS Resources. If present, mustn’t be "inherit".
535         if self.as_resources.is_inherited() {
536             return Err(ValidationError)
537         }
538 
539         self.signed_data.verify_signature(
540             &self.subject_public_key_info
541         )?;
542 
543         Ok(())
544     }
545 
verify_ca( self, issuer: &ResourceCert, strict: bool ) -> Result<ResourceCert, ValidationError>546     pub fn verify_ca(
547         self, issuer: &ResourceCert, strict: bool
548     ) -> Result<ResourceCert, ValidationError> {
549         self.verify_issuer_claim(issuer, strict)?;
550         self.verify_signature(issuer, strict)?;
551         self.verify_resources(issuer, strict)
552     }
553 
verify_ee( self, issuer: &ResourceCert, strict: bool ) -> Result<ResourceCert, ValidationError>554     pub fn verify_ee(
555         self, issuer: &ResourceCert, strict: bool
556     ) -> Result<ResourceCert, ValidationError> {
557         self.verify_issuer_claim(issuer, strict)?;
558         self.verify_signature(issuer, strict)?;
559         self.verify_resources(issuer, strict)
560     }
561 
verify_router( &self, issuer: &ResourceCert, strict: bool ) -> Result<(), ValidationError>562     pub fn verify_router(
563         &self, issuer: &ResourceCert, strict: bool
564     ) -> Result<(), ValidationError> {
565         self.verify_issuer_claim(issuer, strict)?;
566         self.verify_signature(issuer, strict)?;
567         self.verify_as_resources(issuer, strict)
568     }
569 
570 
571     //--- Validation Components
572 
573     /// Inspects basic compliance with section 4 of RFC 6487.
inspect_basics( &self, strict: bool, now: Time ) -> Result<(), ValidationError>574     fn inspect_basics(
575         &self,
576         strict: bool,
577         now: Time
578     ) -> Result<(), ValidationError> {
579         // The following lists all such constraints in the RFC, noting those
580         // that we cannot check here.
581 
582         // 4.2 Serial Number: must be unique over the CA. We cannot check
583         // here, and -- XXX --- probably don’t care?
584 
585         // 4.3 Signature Algorithm: limited to those in RFC 6485. Already
586         // checked in parsing.
587         //
588         // However, RFC 5280 demands that the two mentions of the signature
589         // algorithm are the same. So we do that here.
590         if self.signature != self.signed_data.signature().algorithm() {
591             return Err(ValidationError)
592         }
593 
594         // 4.4 Issuer: must have certain format.
595         Name::validate_rpki(&self.issuer, strict)?;
596 
597         // 4.5 Subject: same as 4.4.
598         Name::validate_rpki(&self.subject, strict)?;
599 
600         // 4.6 Validity. Check according to RFC 5280.
601         self.validity.validate_at(now)?;
602 
603         // 4.7 Subject Public Key Info: limited algorithms.
604         if !self.subject_public_key_info().allow_rpki_cert() {
605             xerr!(return Err(ValidationError))
606         }
607 
608         // 4.8.1. Basic Constraints. Differing requirements for CA and EE
609         // certificates.
610 
611         // 4.8.2. Subject Key Identifier. Must be the SHA-1 hash of the octets
612         // of the subjectPublicKey.
613         if self.subject_key_identifier() !=
614                              self.subject_public_key_info().key_identifier() {
615             return Err(ValidationError)
616         }
617 
618         // 4.8.3. Authority Key Identifier. Differing requirements of TA and
619         // other certificates.
620 
621         // 4.8.4. Key Usage. Differs between CA and EE certificates.
622 
623         // 4.8.5. Extended Key Usage. Must not be present for the kind of
624         // certificates we use here.
625         if self.extended_key_usage().is_some() {
626             return Err(ValidationError)
627         }
628 
629         // 4.8.6. CRL Distribution Points. Differs between TA and other
630         // certificates.
631 
632         // 4.8.7. Authority Information Access. Differs between TA and other
633         // certificates.
634 
635         // 4.8.8.  Subject Information Access. Differs between CA and EE
636         // certificates.
637 
638         // 4.8.9.  Certificate Policies. XXX I think this can be ignored.
639         // At least for now.
640 
641         // 4.8.10.  IP Resources. Differs between trust anchor and issued
642         // certificates.
643 
644         // 4.8.11.  AS Resources. Differs between trust anchor and issued
645         // certificates.
646 
647         Ok(())
648     }
649 
inspect_issued(&self, _strict: bool) -> Result<(), ValidationError>650     fn inspect_issued(&self, _strict: bool) -> Result<(), ValidationError> {
651         // 4.8.6. CRL Distribution Points. There must be one.
652         if self.crl_uri().is_none() {
653             return Err(ValidationError)
654         }
655 
656         Ok(())
657     }
658 
659     /// Validates that the certificate is a valid CA certificate.
660     ///
661     /// Checks the parts that are common in normal and trust anchor CA
662     /// certificates.
inspect_ca_basics( &self, _strict: bool ) -> Result<(), ValidationError>663     fn inspect_ca_basics(
664         &self,
665         _strict: bool
666     ) -> Result<(), ValidationError> {
667         // 4.8.1. Basic Constraints: For a CA it must be present (RFC6487)
668         // und the “cA” flag must be set (RFC5280).
669         if self.basic_ca() != Some(true) {
670             return Err(ValidationError)
671         }
672 
673         // 4.8.4. Key Usage. Bits for CA or not CA have been checked during
674         // parsing already.
675         if self.key_usage() != KeyUsage::Ca {
676             return Err(ValidationError)
677         }
678 
679         // 4.8.8.  Subject Information Access.
680         if self.ca_repository().is_none() || self.rpki_manifest().is_none()
681             || self.signed_object().is_some()
682         {
683             return Err(ValidationError)
684         }
685 
686         Ok(())
687     }
688 
689     /// Inspects a router certificate’s extended key usage.
inspect_router_eku( &self, _strict: bool ) -> Result<(), ValidationError>690     fn inspect_router_eku(
691         &self, _strict: bool
692     ) -> Result<(), ValidationError> {
693         match self.extended_key_usage() {
694             Some(captured) => {
695                 // We already know that the content is a sequence of OIDs
696                 // (that has been tested in take_extended_key_usage). So we
697                 // can return successfully as soon as we find our OID.
698                 let mut captured = captured.clone();
699                 while let Some(oid) = captured.decode_partial(|cons| {
700                     Oid::take_opt_from(cons)
701                 })? {
702                     if oid == oid::KP_BGPSEC_ROUTER {
703                         return Ok(())
704                     }
705                 }
706                 Err(ValidationError)
707             }
708             None => Err(ValidationError)
709         }
710     }
711 
712     /// Verifies that the certificate claims to have been issued by `issuer`.
713     ///
714     /// This is only the first part of verification. You _must_ call
715     /// `verified_signature`, too.
verify_issuer_claim( &self, issuer: &ResourceCert, _strict: bool, ) -> Result<(), ValidationError>716     pub fn verify_issuer_claim(
717         &self,
718         issuer: &ResourceCert,
719         _strict: bool,
720     ) -> Result<(), ValidationError> {
721         // 4.8.3. Authority Key Identifier. Must be present and match the
722         // subject key ID of `issuer`.
723         if self.authority_key_identifier()
724             != Some(issuer.cert.subject_key_identifier())
725         {
726             return Err(ValidationError)
727         }
728 
729         // 4.8.7. Authority Information Access. Must be present and contain
730         // the URI of the issuer certificate. Since we do top-down validation,
731         // we don’t really need that URI so – XXX – leave it unchecked for
732         // now.
733         if self.ca_issuer().is_none() {
734             return Err(ValidationError);
735         }
736 
737         Ok(())
738     }
739 
740     /// Validates the certificate’s signature.
verify_signature( &self, issuer: &Cert, _strict: bool ) -> Result<(), ValidationError>741     pub fn verify_signature(
742         &self,
743         issuer: &Cert,
744         _strict: bool
745     ) -> Result<(), ValidationError> {
746         self.signed_data.verify_signature(
747             issuer.subject_public_key_info()
748         )
749     }
750 
751     /// Validates and extracts the IP and AS resources.
752     ///
753     /// Upon success, this converts the certificate into a `ResourceCert`.
verify_resources( self, issuer: &ResourceCert, _strict: bool ) -> Result<ResourceCert, ValidationError>754     fn verify_resources(
755         self,
756         issuer: &ResourceCert,
757         _strict: bool
758     ) -> Result<ResourceCert, ValidationError> {
759         Ok(ResourceCert {
760             // 4.8.10.  IP Resources. If present, must be encompassed by or
761             // trimmed down to the issuer certificate.
762             v4_resources: issuer.v4_resources.validate_issued(
763                 self.v4_resources(), self.overclaim
764             )?,
765             v6_resources: issuer.v6_resources.validate_issued(
766                 self.v6_resources(), self.overclaim
767             )?,
768             // 4.8.11.  AS Resources. If present, must be encompassed by or
769             // trimmed down to the issuer.
770             as_resources: issuer.as_resources.validate_issued(
771                 self.as_resources(), self.overclaim()
772             )?,
773             cert: self,
774             tal: issuer.tal.clone(),
775         })
776     }
777 
778     /// Validates the AS resources for router certificates.
verify_as_resources( &self, issuer: &ResourceCert, _strict: bool ) -> Result<(), ValidationError>779     fn verify_as_resources(
780         &self,
781         issuer: &ResourceCert,
782         _strict: bool
783     ) -> Result<(), ValidationError> {
784         let _ = issuer.as_resources.validate_issued(
785             self.as_resources(), self.overclaim()
786         )?;
787         Ok(())
788     }
789 }
790 
791 
792 //--- Deref, AsRef, and Borrow
793 
794 impl ops::Deref for Cert {
795     type Target = TbsCert;
796 
deref(&self) -> &Self::Target797     fn deref(&self) -> &Self::Target {
798         &self.tbs
799     }
800 }
801 
802 impl AsRef<Cert> for Cert {
as_ref(&self) -> &Self803     fn as_ref(&self) -> &Self {
804         self
805     }
806 }
807 
808 impl AsRef<TbsCert> for Cert {
as_ref(&self) -> &TbsCert809     fn as_ref(&self) -> &TbsCert {
810         &self.tbs
811     }
812 }
813 
814 impl borrow::Borrow<TbsCert> for Cert {
borrow(&self) -> &TbsCert815     fn borrow(&self) -> &TbsCert {
816         &self.tbs
817     }
818 }
819 
820 
821 //--- Deserialize and Serialize
822 
823 #[cfg(feature = "serde")]
824 impl serde::Serialize for Cert {
serialize<S: serde::Serializer>( &self, serializer: S ) -> Result<S::Ok, S::Error>825     fn serialize<S: serde::Serializer>(
826         &self, serializer: S
827     ) -> Result<S::Ok, S::Error> {
828         let bytes = self.to_captured().into_bytes();
829         let b64 = base64::encode(&bytes);
830         b64.serialize(serializer)
831     }
832 }
833 
834 #[cfg(feature = "serde")]
835 impl<'de> serde::Deserialize<'de> for Cert {
deserialize<D: serde::Deserializer<'de>>( deserializer: D ) -> Result<Self, D::Error>836     fn deserialize<D: serde::Deserializer<'de>>(
837         deserializer: D
838     ) -> Result<Self, D::Error> {
839         use serde::de;
840 
841         let string = String::deserialize(deserializer)?;
842         let decoded = base64::decode(&string).map_err(de::Error::custom)?;
843         let bytes = Bytes::from(decoded);
844         Cert::decode(bytes).map_err(de::Error::custom)
845     }
846 }
847 
848 
849 //------------ TbsCert -------------------------------------------------------
850 
851 /// The data of a resource certificate.
852 #[derive(Clone, Debug)]
853 pub struct TbsCert {
854     /// The serial number.
855     serial_number: Serial,
856 
857     /// The algorithm used for signing the certificate.
858     signature: SignatureAlgorithm,
859 
860     /// The name of the issuer.
861     ///
862     /// It isn’t really relevant in RPKI.
863     issuer: Name,
864 
865     /// The validity of the certificate.
866     validity: Validity,
867 
868     /// The name of the subject of this certificate.
869     ///
870     /// This isn’t really relevant in RPKI.
871     subject: Name,
872 
873     /// Information about the public key of this certificate.
874     subject_public_key_info: PublicKey,
875 
876     /// Basic Constraints extension.
877     ///
878     /// The field indicates whether the extension is present and, if so,
879     /// whether the "cA" boolean is set. See 4.8.1. of RFC 6487.
880     basic_ca: Option<bool>,
881 
882     /// Subject Key Identifier extension.
883     subject_key_identifier: KeyIdentifier,
884 
885     /// Authority Key Identifier extension.
886     authority_key_identifier: Option<KeyIdentifier>,
887 
888     /// Key Usage.
889     ///
890     key_usage: KeyUsage,
891 
892     /// Extended Key Usage.
893     ///
894     /// The value is the content of the DER-encoded sequence of object
895     /// identifiers.
896     extended_key_usage: Option<Captured>,
897 
898     // The following fields are lists of URIs. Each has to have at least one
899     // rsync or HTTPS URI but may contain more. We only support those primary
900     // URIs for now, so we don’t keep the full list but only the one URI we
901     // need.
902 
903     /// CRL Distribution Points.
904     crl_uri: Option<uri::Rsync>,
905 
906     /// Authority Information Access of type `id-ad-caIssuer`.
907     ca_issuer: Option<uri::Rsync>,
908 
909     /// Subject Information Access of type `id-ad-caRepository`
910     ca_repository: Option<uri::Rsync>,
911 
912     /// Subject Information Access of type `id-ad-rpkiManifest`
913     rpki_manifest: Option<uri::Rsync>,
914 
915     /// Subject Information Access of type `id-ad-signedObject`
916     signed_object: Option<uri::Rsync>,
917 
918     /// Subject Information Access of type `id-ad-rpkiNotify`
919     rpki_notify: Option<uri::Https>,
920 
921     /// Certificate Policies
922     ///
923     /// Must be present and critical. RFC 6484 demands there to be a single
924     /// policy with a specific OID and no parameters. RFC 8630 adds a second
925     /// OID for a different way of handling overclaim of resources.
926     ///
927     /// We reflect this choice of policy with an overclaim mode.
928     overclaim: Overclaim,
929 
930     /// IP Resources for the IPv4 address family.
931     v4_resources: IpResources,
932 
933     /// IP Resources for the IPv6 address family.
934     v6_resources: IpResources,
935 
936     /// AS Resources
937     as_resources: AsResources,
938 }
939 
940 
941 /// # Creation and Conversion
942 ///
943 impl TbsCert {
944     /// Creates a new value from the necessary data.
945     #[allow(clippy::too_many_arguments)]
new( serial_number: Serial, issuer: Name, validity: Validity, subject: Option<Name>, subject_public_key_info: PublicKey, key_usage: KeyUsage, overclaim: Overclaim, ) -> Self946     pub fn new(
947         serial_number: Serial,
948         issuer: Name,
949         validity: Validity,
950         subject: Option<Name>,
951         subject_public_key_info: PublicKey,
952         key_usage: KeyUsage,
953         overclaim: Overclaim,
954     ) -> Self {
955         Self {
956             serial_number,
957             signature: SignatureAlgorithm::default(),
958             issuer,
959             validity,
960             subject: {
961                 subject.unwrap_or_else(||
962                     subject_public_key_info.to_subject_name()
963                 )
964             },
965             subject_key_identifier: {
966                 KeyIdentifier::from_public_key(&subject_public_key_info)
967             },
968             subject_public_key_info,
969             basic_ca: None,
970             authority_key_identifier: None,
971             key_usage,
972             extended_key_usage: None,
973             crl_uri: None,
974             ca_issuer: None,
975             ca_repository: None,
976             rpki_manifest: None,
977             signed_object: None,
978             rpki_notify: None,
979             overclaim,
980             v4_resources: IpResources::missing(),
981             v6_resources: IpResources::missing(),
982             as_resources: AsResources::missing(),
983         }
984     }
985 
986     /// Converts the value into a signed certificate.
into_cert<S: Signer>( self, signer: &S, key: &S::KeyId, ) -> Result<Cert, SigningError<S::Error>>987     pub fn into_cert<S: Signer>(
988         self,
989         signer: &S,
990         key: &S::KeyId,
991     ) -> Result<Cert, SigningError<S::Error>> {
992         let data = Captured::from_values(Mode::Der, self.encode_ref());
993         let signature = signer.sign(key, self.signature, &data)?;
994         Ok(Cert {
995             signed_data: SignedData::new(data, signature),
996             tbs: self
997         })
998     }
999 }
1000 
1001 
1002 /// # Data Access
1003 ///
1004 impl TbsCert {
1005     /// Returns the serial number of the certificate.
serial_number(&self) -> Serial1006     pub fn serial_number(&self) -> Serial {
1007         self.serial_number
1008     }
1009 
1010     /// Set the serial number of the certificate.
set_serial_number<S: Into<Serial>>(&mut self, serial: S)1011     pub fn set_serial_number<S: Into<Serial>>(&mut self, serial: S) {
1012         self.serial_number = serial.into()
1013     }
1014 
1015     /// Returns a reference to the issuer.
issuer(&self) -> &Name1016     pub fn issuer(&self) -> &Name {
1017         &self.issuer
1018     }
1019 
1020     /// Sets the issuer.
set_issuer(&mut self, name: Name)1021     pub fn set_issuer(&mut self, name: Name) {
1022         self.issuer = name
1023     }
1024 
1025     /// Returns a reference to the validity.
validity(&self) -> Validity1026     pub fn validity(&self) -> Validity {
1027         self.validity
1028     }
1029 
1030     /// Sets the validity.
set_validity(&mut self, validity: Validity)1031     pub fn set_validity(&mut self, validity: Validity) {
1032         self.validity = validity
1033     }
1034 
1035     /// Returns a reference to the subject.
subject(&self) -> &Name1036     pub fn subject(&self) -> &Name {
1037         &self.subject
1038     }
1039 
1040     /// Sets the subject.
set_subject(&mut self, subject: Name)1041     pub fn set_subject(&mut self, subject: Name) {
1042         self.subject = subject
1043     }
1044 
1045     /// Returns a reference to the public key.
subject_public_key_info(&self) -> &PublicKey1046     pub fn subject_public_key_info(&self) -> &PublicKey {
1047         &self.subject_public_key_info
1048     }
1049 
1050     /// Sets the public key.
1051     ///
1052     /// This sets both the value of the `subject_public_key_info` field to
1053     /// the public key itself as well as the `subject_public_key_identifier`
1054     /// to the identifier of that key.
set_subject_public_key(&mut self, key: PublicKey)1055     pub fn set_subject_public_key(&mut self, key: PublicKey) {
1056         self.subject_key_identifier = KeyIdentifier::from_public_key(&key);
1057         self.subject_public_key_info = key;
1058     }
1059 
1060     /// Returns the cA field of the basic constraints extension if present.
basic_ca(&self) -> Option<bool>1061     pub fn basic_ca(&self) -> Option<bool> {
1062         self.basic_ca
1063     }
1064 
1065     /// Sets the basic constraints extension.
1066     ///
1067     /// If `value` is `None`, the extension will be absent. If it is some
1068     /// value, the boolean is the value of the `cA` field of the extension.
set_basic_ca(&mut self, value: Option<bool>)1069     pub fn set_basic_ca(&mut self, value: Option<bool>) {
1070         self.basic_ca = value
1071     }
1072 
1073     /// Returns a reference to the subject key identifier.
1074     ///
1075     /// There is no method to set this extension as this happens automatically
1076     /// when the subject public key is set via [`set_subject_public_key`].
1077     ///
1078     /// [`set_subject_public_key`]: #method.set_subject_public_key
subject_key_identifier(&self) -> KeyIdentifier1079     pub fn subject_key_identifier(&self) -> KeyIdentifier {
1080         self.subject_key_identifier
1081     }
1082 
1083     /// Returns a reference to the authority key identifier if present.
authority_key_identifier(&self) -> Option<KeyIdentifier>1084     pub fn authority_key_identifier(&self) -> Option<KeyIdentifier> {
1085         self.authority_key_identifier
1086     }
1087 
1088     /// Sets the authority key identifier extension.
set_authority_key_identifier( &mut self, id: Option<KeyIdentifier> )1089     pub fn set_authority_key_identifier(
1090         &mut self,
1091         id: Option<KeyIdentifier>
1092     ) {
1093         self.authority_key_identifier = id
1094     }
1095 
1096     /// Returns the key usage of the certificate.
key_usage(&self) -> KeyUsage1097     pub fn key_usage(&self) -> KeyUsage {
1098         self.key_usage
1099     }
1100 
1101     /// Sets the key usage of the certificate.
set_key_usage(&mut self, key_usage: KeyUsage)1102     pub fn set_key_usage(&mut self, key_usage: KeyUsage) {
1103         self.key_usage = key_usage
1104     }
1105 
1106     /// Returns a reference to the extended key usage if present.
1107     ///
1108     /// Since this field isn’t allowed in any certificate used for RPKI
1109     /// objects directly, we do not currently support setting this field.
extended_key_usage(&self) -> Option<&Captured>1110     pub fn extended_key_usage(&self) -> Option<&Captured> {
1111         self.extended_key_usage.as_ref()
1112     }
1113 
1114     /// Returns a reference to the certificate’s CRL distribution point.
crl_uri(&self) -> Option<&uri::Rsync>1115     pub fn crl_uri(&self) -> Option<&uri::Rsync> {
1116         self.crl_uri.as_ref()
1117     }
1118 
1119     /// Sets the CRL distribution point.
set_crl_uri(&mut self, uri: Option<uri::Rsync>)1120     pub fn set_crl_uri(&mut self, uri: Option<uri::Rsync>) {
1121         self.crl_uri = uri
1122     }
1123 
1124     /// Returns a reference to *caIssuer* AIA rsync URI if present.
ca_issuer(&self) -> Option<&uri::Rsync>1125     pub fn ca_issuer(&self) -> Option<&uri::Rsync> {
1126         self.ca_issuer.as_ref()
1127     }
1128 
1129     /// Sets the *caIssuer* AIA rsync URI.
set_ca_issuer(&mut self, uri: Option<uri::Rsync>)1130     pub fn set_ca_issuer(&mut self, uri: Option<uri::Rsync>) {
1131         self.ca_issuer= uri
1132     }
1133 
1134     /// Returns a reference to the *caRepository* SIA rsync URI if present.
ca_repository(&self) -> Option<&uri::Rsync>1135     pub fn ca_repository(&self) -> Option<&uri::Rsync> {
1136         self.ca_repository.as_ref()
1137     }
1138 
1139     /// Sets the *caRepository* SIA rsync URI.
set_ca_repository(&mut self, uri: Option<uri::Rsync>)1140     pub fn set_ca_repository(&mut self, uri: Option<uri::Rsync>) {
1141         self.ca_repository = uri
1142     }
1143 
1144     /// Returns a reference to the *rpkiManifest* SIA rsync URI if present.
rpki_manifest(&self) -> Option<&uri::Rsync>1145     pub fn rpki_manifest(&self) -> Option<&uri::Rsync> {
1146         self.rpki_manifest.as_ref()
1147     }
1148 
1149     /// Sets the *rpkiManifest* SIA rsync URI.
set_rpki_manifest(&mut self, uri: Option<uri::Rsync>)1150     pub fn set_rpki_manifest(&mut self, uri: Option<uri::Rsync>) {
1151         self.rpki_manifest = uri
1152     }
1153 
1154     /// Returns a reference to the *signedObject* SIA rsync URI if present.
signed_object(&self) -> Option<&uri::Rsync>1155     pub fn signed_object(&self) -> Option<&uri::Rsync> {
1156         self.signed_object.as_ref()
1157     }
1158 
1159     /// Sets the *signedObject* SIA rsync URI.
set_signed_object(&mut self, uri: Option<uri::Rsync>)1160     pub fn set_signed_object(&mut self, uri: Option<uri::Rsync>) {
1161         self.signed_object = uri
1162     }
1163 
1164     /// Returns a reference to the *rpkiNotify* SIA HTTPS URI if present.
rpki_notify(&self) -> Option<&uri::Https>1165     pub fn rpki_notify(&self) -> Option<&uri::Https> {
1166         self.rpki_notify.as_ref()
1167     }
1168 
1169     /// Sets the *rpkiNotify* SIA HTTPS URI.
set_rpki_notify(&mut self, uri: Option<uri::Https>)1170     pub fn set_rpki_notify(&mut self, uri: Option<uri::Https>) {
1171         self.rpki_notify = uri
1172     }
1173 
1174     /// Returns the overclaim mode of the certificate.
overclaim(&self) -> Overclaim1175     pub fn overclaim(&self) -> Overclaim {
1176         self.overclaim
1177     }
1178 
1179     /// Sets the overclaim mode of the certificate.
set_overclaim(&mut self, overclaim: Overclaim)1180     pub fn set_overclaim(&mut self, overclaim: Overclaim) {
1181         self.overclaim = overclaim
1182     }
1183 
1184     /// Returns a reference to the IPv4 address resources if present.
v4_resources(&self) -> &IpResources1185     pub fn v4_resources(&self) -> &IpResources {
1186         &self.v4_resources
1187     }
1188 
1189     /// Set the IPv4 address resources.
set_v4_resources(&mut self, resources: IpResources)1190     pub fn set_v4_resources(&mut self, resources: IpResources) {
1191         self.v4_resources = resources
1192     }
1193 
1194     /// Sets the IPv4 address resources to inherit.
set_v4_resources_inherit(&mut self)1195     pub fn set_v4_resources_inherit(&mut self) {
1196         self.set_v4_resources(IpResources::inherit())
1197     }
1198 
1199     /// Builds the blocks IPv4 address resources.
build_v4_resource_blocks<F>(&mut self, op: F) where F: FnOnce(&mut IpBlocksBuilder)1200     pub fn build_v4_resource_blocks<F>(&mut self, op: F)
1201     where F: FnOnce(&mut IpBlocksBuilder) {
1202         let mut builder = IpResourcesBuilder::new();
1203         builder.blocks(op);
1204         self.set_v4_resources(builder.finalize())
1205     }
1206 
1207     /// Builds the IPv4 address resources from an iterator over blocks.
v4_resources_from_iter<I>(&mut self, iter: I) where I: IntoIterator<Item=IpBlock>1208     pub fn v4_resources_from_iter<I>(&mut self, iter: I)
1209     where I: IntoIterator<Item=IpBlock> {
1210         self.v4_resources = IpResources::blocks(IpBlocks::from_iter(iter))
1211     }
1212 
1213     /// Returns a reference to the IPv6 address resources if present.
v6_resources(&self) -> &IpResources1214     pub fn v6_resources(&self) -> &IpResources {
1215         &self.v6_resources
1216     }
1217 
1218     /// Set the IPv6 address resources.
set_v6_resources(&mut self, resources: IpResources)1219     pub fn set_v6_resources(&mut self, resources: IpResources) {
1220         self.v6_resources = resources
1221     }
1222 
1223     /// Sets the IPv6 address resources to inherit.
set_v6_resources_inherit(&mut self)1224     pub fn set_v6_resources_inherit(&mut self) {
1225         self.set_v6_resources(IpResources::inherit())
1226     }
1227 
1228     /// Builds the blocks IPv6 address resources.
build_v6_resource_blocks<F>(&mut self, op: F) where F: FnOnce(&mut IpBlocksBuilder)1229     pub fn build_v6_resource_blocks<F>(&mut self, op: F)
1230     where F: FnOnce(&mut IpBlocksBuilder) {
1231         let mut builder = IpResourcesBuilder::new();
1232         builder.blocks(op);
1233         self.set_v6_resources(builder.finalize())
1234     }
1235 
1236     /// Builds the IPv6 address resources from an iterator over blocks
v6_resources_from_iter<I>(&mut self, iter: I) where I: IntoIterator<Item=IpBlock>1237     pub fn v6_resources_from_iter<I>(&mut self, iter: I)
1238     where I: IntoIterator<Item=IpBlock> {
1239         self.v6_resources = IpResources::blocks(IpBlocks::from_iter(iter))
1240     }
1241 
1242     /// Returns whether the certificate has any IP resources at all.
has_ip_resources(&self) -> bool1243     pub fn has_ip_resources(&self) -> bool {
1244         self.v4_resources.is_present() || self.v6_resources().is_present()
1245     }
1246 
1247     /// Returns a reference to the AS resources.
as_resources(&self) -> &AsResources1248     pub fn as_resources(&self) -> &AsResources {
1249         &self.as_resources
1250     }
1251 
1252     /// Set the AS resources.
set_as_resources(&mut self, resources: AsResources)1253     pub fn set_as_resources(&mut self, resources: AsResources) {
1254         self.as_resources = resources
1255     }
1256 
1257     /// Sets the AS resources to inherit.
set_as_resources_inherit(&mut self)1258     pub fn set_as_resources_inherit(&mut self) {
1259         self.set_as_resources(AsResources::inherit())
1260     }
1261 
1262     /// Builds the blocks AS resources.
build_as_resource_blocks<F>(&mut self, op: F) where F: FnOnce(&mut AsBlocksBuilder)1263     pub fn build_as_resource_blocks<F>(&mut self, op: F)
1264     where F: FnOnce(&mut AsBlocksBuilder) {
1265         let mut builder = AsResourcesBuilder::new();
1266         builder.blocks(op);
1267         self.set_as_resources(builder.finalize())
1268     }
1269 
1270     /// Builds the AS resources from an iterator over blocks.
as_resources_from_iter<I>(&mut self, iter: I) where I: IntoIterator<Item = AsBlock>1271     pub fn as_resources_from_iter<I>(&mut self, iter: I)
1272     where I: IntoIterator<Item = AsBlock> {
1273         self.as_resources = AsResources::blocks(AsBlocks::from_iter(iter))
1274     }
1275 
1276     /// Returns whether this is a CA certificate if validation succeeds.
is_ca(&self) -> bool1277     pub fn is_ca(&self) -> bool {
1278         self.basic_ca.unwrap_or(false)
1279     }
1280 
1281     /// Returns whether this is a self-signed certificate if valid.
is_self_signed(&self) -> bool1282     pub fn is_self_signed(&self) -> bool {
1283         match self.authority_key_identifier {
1284             Some(aki) => aki == self.subject_key_identifier,
1285             None => true
1286         }
1287     }
1288 }
1289 
1290 
1291 /// # Decoding and Encoding
1292 ///
1293 impl TbsCert {
1294     /// Parses the content of a Certificate sequence.
from_constructed<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<Self, S::Err>1295     pub fn from_constructed<S: decode::Source>(
1296         cons: &mut decode::Constructed<S>
1297     ) -> Result<Self, S::Err> {
1298         cons.take_sequence(|cons| {
1299             // version [0] EXPLICIT Version DEFAULT v1.
1300             //  -- we need extensions so apparently, we want v3 which,
1301             //     confusingly, is 2.
1302             cons.take_constructed_if(Tag::CTX_0, |c| c.skip_u8_if(2))?;
1303 
1304             let serial_number = Serial::take_from(cons)?;
1305             let signature = SignatureAlgorithm::x509_take_from(cons)?;
1306             let issuer = Name::take_from(cons)?;
1307             let validity = Validity::take_from(cons)?;
1308             let subject = Name::take_from(cons)?;
1309             let subject_public_key_info = PublicKey::take_from(cons)?;
1310 
1311 
1312             // issuerUniqueID and subjectUniqueID must not be present in
1313             // resource certificates. So extension is next.
1314 
1315             let mut basic_ca = None;
1316             let mut subject_key_id = None;
1317             let mut authority_key_id = None;
1318             let mut key_usage = None;
1319             let mut extended_key_usage = None;
1320             let mut crl_uri = None;
1321             let mut ca_issuer = None;
1322             let mut sia = None;
1323             let mut overclaim = None;
1324             let mut ip_resources = None;
1325             let mut ip_overclaim = None;
1326             let mut as_resources = None;
1327             let mut as_overclaim = None;
1328 
1329             cons.take_constructed_if(Tag::CTX_3, |c| c.take_sequence(|cons| {
1330                 while let Some(()) = cons.take_opt_sequence(|cons| {
1331                     let id = Oid::take_from(cons)?;
1332                     let critical = cons.take_opt_bool()?.unwrap_or(false);
1333                     let value = OctetString::take_from(cons)?;
1334                     Mode::Der.decode(value.to_source(), |content| {
1335                         if id == oid::CE_BASIC_CONSTRAINTS {
1336                             Self::take_basic_constraints(
1337                                 content, &mut basic_ca
1338                             )
1339                         } else if id == oid::CE_SUBJECT_KEY_IDENTIFIER {
1340                             Self::take_subject_key_identifier(
1341                                 content, &mut subject_key_id
1342                             )
1343                         } else if id == oid::CE_AUTHORITY_KEY_IDENTIFIER {
1344                             Self::take_authority_key_identifier(
1345                                 content, &mut authority_key_id
1346                             )
1347                         } else if id == oid::CE_KEY_USAGE {
1348                             Self::take_key_usage(
1349                                 content, &mut key_usage
1350                             )
1351                         } else if id == oid::CE_EXTENDED_KEY_USAGE {
1352                             Self::take_extended_key_usage(
1353                                 content, &mut extended_key_usage
1354                             )
1355                         } else if id == oid::CE_CRL_DISTRIBUTION_POINTS {
1356                             Self::take_crl_distribution_points(
1357                                 content, &mut crl_uri
1358                             )
1359                         } else if id == oid::PE_AUTHORITY_INFO_ACCESS {
1360                             Self::take_authority_info_access(
1361                                 content, &mut ca_issuer
1362                             )
1363                         } else if id == oid::PE_SUBJECT_INFO_ACCESS {
1364                             Self::take_subject_info_access(
1365                                 content, &mut sia
1366                             )
1367                         } else if id == oid::CE_CERTIFICATE_POLICIES {
1368                             Self::take_certificate_policies(
1369                                 content, &mut overclaim
1370                             )
1371                         } else if let Some(m) = Overclaim::from_ip_res(&id) {
1372                             ip_overclaim = Some(m);
1373                             Self::take_ip_resources(content, &mut ip_resources)
1374                         } else if let Some(m) = Overclaim::from_as_res(&id) {
1375                             as_overclaim = Some(m);
1376                             Self::take_as_resources(content, &mut as_resources)
1377                         } else if critical {
1378                             xerr!(Err(decode::Malformed))
1379                         } else {
1380                             // RFC 5280 says we can ignore non-critical
1381                             // extensions we don’t know of. RFC 6487
1382                             // agrees. So let’s do that.
1383                             Ok(())
1384                         }
1385                     })?;
1386                     Ok(())
1387                 })? { }
1388                 Ok(())
1389             }))?;
1390 
1391             if ip_resources.is_none() && as_resources.is_none() {
1392                 xerr!(return Err(decode::Malformed.into()))
1393             }
1394             if ip_resources.is_some() && ip_overclaim != overclaim {
1395                 xerr!(return Err(decode::Malformed.into()))
1396             }
1397             if as_resources.is_some() && as_overclaim != overclaim {
1398                 xerr!(return Err(decode::Malformed.into()))
1399             }
1400             let (v4_resources, v6_resources) = match ip_resources {
1401                 Some(res) => res,
1402                 None => (None, None)
1403             };
1404             let (ca_repository, rpki_manifest, signed_object, rpki_notify) = {
1405                 match sia {
1406                     Some(sia) => (
1407                         sia.ca_repository, sia.rpki_manifest,
1408                         sia.signed_object, sia.rpki_notify
1409                     ),
1410                     None => (None, None, None, None)
1411                 }
1412             };
1413 
1414             Ok(Self {
1415                 serial_number,
1416                 signature,
1417                 issuer,
1418                 validity,
1419                 subject,
1420                 subject_public_key_info,
1421                 basic_ca,
1422                 subject_key_identifier:
1423                     subject_key_id.ok_or(decode::Malformed)?,
1424                 authority_key_identifier: authority_key_id,
1425                 key_usage: key_usage.ok_or(decode::Malformed)?,
1426                 extended_key_usage,
1427                 crl_uri,
1428                 ca_issuer,
1429                 ca_repository,
1430                 rpki_manifest,
1431                 signed_object,
1432                 rpki_notify,
1433                 overclaim: overclaim.ok_or(decode::Malformed)?,
1434                 v4_resources: v4_resources.unwrap_or_else(
1435                     IpResources::missing
1436                 ),
1437                 v6_resources: v6_resources.unwrap_or_else(
1438                     IpResources::missing
1439                 ),
1440                 as_resources: as_resources.unwrap_or_else(
1441                     AsResources::missing
1442                 ),
1443             })
1444         })
1445     }
1446 
1447     /// Parses the Basic Constraints extension.
1448     ///
1449     /// ```text
1450     /// BasicConstraints        ::= SEQUENCE {
1451     ///     cA                      BOOLEAN DEFAULT FALSE,
1452     ///     pathLenConstraint       INTEGER (0..MAX) OPTIONAL
1453     /// }
1454     /// ```
1455     ///
1456     /// For resource certificates, the extension must be critical. It must be
1457     /// present for CA certificates and must not be present for EE
1458     /// certificates. RFC 6487 says that the issued decides whether the cA
1459     /// boolean is to be set or not, but for all CA certificates it must be
1460     /// set (required indirectly by requiring the keyCertSign bit set in
1461     /// the key usage extension) so really it must always be true if the
1462     /// extension is present.
1463     ///
1464     /// The pathLenConstraint field must not be present.
take_basic_constraints<S: decode::Source>( cons: &mut decode::Constructed<S>, basic_ca: &mut Option<bool>, ) -> Result<(), S::Err>1465     pub(crate) fn take_basic_constraints<S: decode::Source>(
1466         cons: &mut decode::Constructed<S>,
1467         basic_ca: &mut Option<bool>,
1468     ) -> Result<(), S::Err> {
1469         update_once(basic_ca, || {
1470             cons.take_sequence(|cons| cons.take_opt_bool())
1471                 .map(|ca| ca.unwrap_or(false))
1472         })
1473     }
1474 
1475     /// Parses the Subject Key Identifier extension.
1476     ///
1477     /// ```text
1478     /// SubjectKeyIdentifier ::= KeyIdentifier
1479     /// ```
1480     ///
1481     /// The extension must be present and contain the 160 bit SHA-1 hash of
1482     /// the value of the DER-encoded bit string of the subject public key.
1483     ///
1484     /// Conforming CAs MUST mark this extension as non-critical.
take_subject_key_identifier<S: decode::Source>( cons: &mut decode::Constructed<S>, subject_key_id: &mut Option<KeyIdentifier>, ) -> Result<(), S::Err>1485     fn take_subject_key_identifier<S: decode::Source>(
1486         cons: &mut decode::Constructed<S>,
1487         subject_key_id: &mut Option<KeyIdentifier>,
1488     ) -> Result<(), S::Err> {
1489         update_once(subject_key_id, || KeyIdentifier::take_from(cons))
1490     }
1491 
1492     /// Parses the Authority Key Identifier extension.
1493     ///
1494     /// ```text
1495     /// AuthorityKeyIdentifier ::= SEQUENCE {
1496     ///   keyIdentifier             [0] KeyIdentifier           OPTIONAL,
1497     ///   authorityCertIssuer       [1] GeneralNames            OPTIONAL,
1498     ///   authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
1499     /// ```
1500     ///
1501     /// Must be present except in self-signed CA certificates where it is
1502     /// optional. The keyIdentifier field must be present, the other must not
1503     /// be.
take_authority_key_identifier<S: decode::Source>( cons: &mut decode::Constructed<S>, authority_key_id: &mut Option<KeyIdentifier>, ) -> Result<(), S::Err>1504     fn take_authority_key_identifier<S: decode::Source>(
1505         cons: &mut decode::Constructed<S>,
1506         authority_key_id: &mut Option<KeyIdentifier>,
1507     ) -> Result<(), S::Err> {
1508         update_once(authority_key_id, || {
1509             cons.take_sequence(|cons| {
1510                 cons.take_value_if(Tag::CTX_0, KeyIdentifier::from_content)
1511             })
1512         })
1513     }
1514 
1515     /// Parses the Key Usage extension.
1516     ///
1517     /// ```text
1518     /// KeyUsage ::= BIT STRING {
1519     ///      digitalSignature        (0),
1520     ///      nonRepudiation          (1), -- recent editions of X.509 have
1521     ///                           -- renamed this bit to contentCommitment
1522     ///      keyEncipherment         (2),
1523     ///      dataEncipherment        (3),
1524     ///      keyAgreement            (4),
1525     ///      keyCertSign             (5),
1526     ///      cRLSign                 (6),
1527     ///      encipherOnly            (7),
1528     ///      decipherOnly            (8) }
1529     ///
1530     /// Must be present. In CA certificates, keyCertSign and
1531     /// CRLSign must be set, in EE certificates, digitalSignatures must be
1532     /// set.
take_key_usage<S: decode::Source>( cons: &mut decode::Constructed<S>, key_usage: &mut Option<KeyUsage> ) -> Result<(), S::Err>1533     pub(crate) fn take_key_usage<S: decode::Source>(
1534         cons: &mut decode::Constructed<S>,
1535         key_usage: &mut Option<KeyUsage>
1536     ) -> Result<(), S::Err> {
1537         update_once(key_usage, || {
1538             let bits = BitString::take_from(cons)?;
1539             if bits.bit(5) && bits.bit(6) {
1540                 Ok(KeyUsage::Ca)
1541             }
1542             else if bits.bit(0) {
1543                 Ok(KeyUsage::Ee)
1544             }
1545             else {
1546                 Err(decode::Malformed.into())
1547             }
1548         })
1549     }
1550 
1551     /// Parses the Extended Key Usage extension.
1552     ///
1553     /// ```text
1554     /// ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1555     /// KeyPurposeId ::= OBJECT IDENTIFIER
1556     /// ```
1557     ///
1558     /// May only be present in EE certificates issued to devices.
take_extended_key_usage<S: decode::Source>( cons: &mut decode::Constructed<S>, extended_key_usage: &mut Option<Captured> ) -> Result<(), S::Err>1559     pub(crate) fn take_extended_key_usage<S: decode::Source>(
1560         cons: &mut decode::Constructed<S>,
1561         extended_key_usage: &mut Option<Captured>
1562     ) -> Result<(), S::Err> {
1563         update_once(extended_key_usage, || {
1564             let res = cons.take_sequence(|c| c.capture_all())?;
1565             res.clone().decode(|cons| {
1566                 Oid::skip_in(cons)?;
1567                 while Oid::skip_opt_in(cons)?.is_some() { }
1568                 Ok(res)
1569             }).map_err(Into::into)
1570         })
1571     }
1572 
1573     /// Parses the CRL Distribution Points extension.
1574     ///
1575     /// ```text
1576     /// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
1577     ///
1578     /// DistributionPoint ::= SEQUENCE {
1579     ///    distributionPoint       [0]     DistributionPointName OPTIONAL,
1580     ///    reasons                 [1]     ReasonFlags OPTIONAL,
1581     ///    cRLIssuer               [2]     GeneralNames OPTIONAL }
1582     ///
1583     /// DistributionPointName ::= CHOICE {
1584     ///    fullName                [0]     GeneralNames,
1585     ///    nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
1586     /// ```
1587     ///
1588     /// Must be present except in self-signed certificates.
1589     ///
1590     /// It must contain exactly one Distribution Point. Only its
1591     /// distributionPoint field must be present and it must contain
1592     /// the fullName choice which can be one or more uniformResourceIdentifier
1593     /// choices.
take_crl_distribution_points<S: decode::Source>( cons: &mut decode::Constructed<S>, crl_uri: &mut Option<uri::Rsync> ) -> Result<(), S::Err>1594     fn take_crl_distribution_points<S: decode::Source>(
1595         cons: &mut decode::Constructed<S>,
1596         crl_uri: &mut Option<uri::Rsync>
1597     ) -> Result<(), S::Err> {
1598         update_once(crl_uri, || {
1599             // CRLDistributionPoints
1600             cons.take_sequence(|cons| {
1601                 // DistributionPoint
1602                 cons.take_sequence(|cons| {
1603                     // distributionPoint
1604                     cons.take_constructed_if(Tag::CTX_0, |cons| {
1605                         // fullName
1606                         cons.take_constructed_if(Tag::CTX_0, |cons| {
1607                             // GeneralNames content
1608                             take_general_names_content(
1609                                 cons, uri::Rsync::from_bytes
1610                             )
1611                         })
1612                     })
1613                 })
1614             })
1615         })
1616     }
1617 
1618     /// Parses the Authority Information Access extension.
1619     ///
1620     /// ```text
1621     /// AuthorityInfoAccessSyntax  ::=
1622     ///         SEQUENCE SIZE (1..MAX) OF AccessDescription
1623     ///
1624     /// AccessDescription  ::=  SEQUENCE {
1625     ///         accessMethod          OBJECT IDENTIFIER,
1626     ///         accessLocation        GeneralName  }
1627     /// ```
1628     ///
1629     /// Must be present except in self-signed certificates. Must contain
1630     /// exactly one entry with accessMethod id-ad-caIssuers and URIs in the
1631     /// generalName. There must be one rsync URI, there may be more. We only
1632     /// support the one, though, so we’ll ignore the rest.
take_authority_info_access<S: decode::Source>( cons: &mut decode::Constructed<S>, ca_issuer: &mut Option<uri::Rsync> ) -> Result<(), S::Err>1633     fn take_authority_info_access<S: decode::Source>(
1634         cons: &mut decode::Constructed<S>,
1635         ca_issuer: &mut Option<uri::Rsync>
1636     ) -> Result<(), S::Err> {
1637         update_once(ca_issuer, || {
1638             cons.take_sequence(|cons| {
1639                 cons.take_sequence(|cons| {
1640                     oid::AD_CA_ISSUERS.skip_if(cons)?;
1641                     take_general_names_content(cons, uri::Rsync::from_bytes)
1642                 })
1643             })
1644         })
1645     }
1646 
1647     /// Parses the Subject Information Access extension.
1648     ///
1649     /// ```text
1650     /// SubjectInfoAccessSyntax  ::=
1651     ///         SEQUENCE SIZE (1..MAX) OF AccessDescription
1652     ///
1653     /// AccessDescription  ::=  SEQUENCE {
1654     ///         accessMethod          OBJECT IDENTIFIER,
1655     ///         accessLocation        GeneralName  }
1656     /// ```
1657     ///
1658     /// Must be present.
1659     ///
1660     /// For CA certificates, there must be two AccessDescriptions, one with
1661     /// id-ad-caRepository and one with id-ad-rpkiManifest, both with rsync
1662     /// URIs. Additional id-ad-rpkiManifest descriptions may be present with
1663     /// additional access mechanisms for the manifest.
1664     ///
1665     /// Additionally, an id-ad-rpkiNotify may be present with a HTTPS URI.
1666     ///
1667     /// For EE certificates, there must at least one AccessDescription value
1668     /// with an id-ad-signedObject access method.
1669     ///
1670     /// Since we don’t necessarily know what kind of certificate we have yet,
1671     /// we may accept the wrong kind here. This needs to be checked later.
take_subject_info_access<S: decode::Source>( cons: &mut decode::Constructed<S>, sia: &mut Option<Sia>, ) -> Result<(), S::Err>1672     pub(crate) fn take_subject_info_access<S: decode::Source>(
1673         cons: &mut decode::Constructed<S>,
1674         sia: &mut Option<Sia>,
1675     ) -> Result<(), S::Err> {
1676         update_once(sia, || {
1677             let mut sia = Sia::default();
1678             let mut others_seen = false;
1679             cons.take_sequence(|cons| {
1680                 while let Some(()) = cons.take_opt_sequence(|cons| {
1681                     let oid = Oid::take_from(cons)?;
1682                     if oid == oid::AD_CA_REPOSITORY {
1683                         update_first(&mut sia.ca_repository, || {
1684                             take_general_name(
1685                                 cons, uri::Rsync::from_bytes
1686                             )
1687                         })
1688                     }
1689                     else if oid == oid::AD_RPKI_MANIFEST {
1690                         update_first(&mut sia.rpki_manifest, || {
1691                             take_general_name(
1692                                 cons, uri::Rsync::from_bytes
1693                             )
1694                         })
1695                     }
1696                     else if oid == oid::AD_SIGNED_OBJECT {
1697                         update_first(&mut sia.signed_object, || {
1698                             take_general_name(
1699                                 cons, uri::Rsync::from_bytes
1700                             )
1701                         })
1702                     }
1703                     else if oid == oid::AD_RPKI_NOTIFY {
1704                         update_first(&mut sia.rpki_notify, || {
1705                             take_general_name(
1706                                 cons, uri::Https::from_bytes
1707                             )
1708                         })
1709                     }
1710                     else {
1711                         others_seen = true;
1712                         // XXX Presumably it is fine to just skip over these
1713                         //     things. Since this is DER, it can’t be tricked
1714                         //     into reading forever.
1715                         cons.skip_all()
1716                     }
1717                 })? { }
1718                 Ok(())
1719             })?;
1720             Ok(sia)
1721         })
1722     }
1723 
1724     /// Parses the Certificate Policies extension.
1725     ///
1726     /// ```text
1727     /// certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
1728     ///
1729     /// PolicyInformation ::= SEQUENCE {
1730     ///     policyIdentifier   CertPolicyId,
1731     ///     policyQualifiers   SEQUENCE SIZE (1..MAX) OF
1732     ///                             PolicyQualifierInfo OPTIONAL }
1733     ///
1734     /// CertPolicyId ::= OBJECT IDENTIFIER
1735     ///
1736     /// [...]
1737     /// ```
1738     ///
1739     /// Must be present. There are two policyIdentifiers for resource
1740     /// certificates. They define how we deal with overclaim of resources.
1741     /// The policyQualifiers are not interesting for us.
take_certificate_policies<S: decode::Source>( cons: &mut decode::Constructed<S>, overclaim: &mut Option<Overclaim>, ) -> Result<(), S::Err>1742     fn take_certificate_policies<S: decode::Source>(
1743         cons: &mut decode::Constructed<S>,
1744         overclaim: &mut Option<Overclaim>,
1745     ) -> Result<(), S::Err> {
1746         update_once(overclaim, || {
1747             cons.take_sequence(|cons| {
1748                 cons.take_sequence(|cons| {
1749                     let res = Overclaim::from_policy(&Oid::take_from(cons)?)?;
1750                     // policyQualifiers. This is a sequence of sequences with
1751                     // stuff we don’t really care about. Let’s skip all the
1752                     // rest.
1753                     cons.skip_all()?;
1754                     Ok(res)
1755                 })
1756             })
1757         })
1758     }
1759 
1760     /// Parses the IP Resources extension.
take_ip_resources<S: decode::Source>( cons: &mut decode::Constructed<S>, ip_resources: &mut Option<(Option<IpResources>, Option<IpResources>)> ) -> Result<(), S::Err>1761     fn take_ip_resources<S: decode::Source>(
1762         cons: &mut decode::Constructed<S>,
1763         ip_resources: &mut Option<(Option<IpResources>, Option<IpResources>)>
1764     ) -> Result<(), S::Err> {
1765         update_once(ip_resources, || IpResources::take_families_from(cons))
1766     }
1767 
1768     /// Parses the AS Resources extension.
take_as_resources<S: decode::Source>( cons: &mut decode::Constructed<S>, as_resources: &mut Option<AsResources> ) -> Result<(), S::Err>1769     fn take_as_resources<S: decode::Source>(
1770         cons: &mut decode::Constructed<S>,
1771         as_resources: &mut Option<AsResources>
1772     ) -> Result<(), S::Err> {
1773         update_once(as_resources, || {
1774             AsResources::take_from(cons)
1775         })
1776     }
1777 
1778     /// Returns an encoder for the value.
encode_ref(&self) -> impl encode::Values + '_1779     pub fn encode_ref(&self) -> impl encode::Values + '_ {
1780         encode::sequence((
1781             encode::sequence_as(Tag::CTX_0, 2.encode()), // version
1782             self.serial_number.encode(),
1783             self.signature.x509_encode(),
1784             self.issuer.encode_ref(),
1785             self.validity.encode(),
1786             self.subject.encode_ref(),
1787             self.subject_public_key_info.encode_ref(),
1788             // no issuerUniqueID
1789             // no subjectUniqueID
1790             // extensions
1791             encode::sequence_as(Tag::CTX_3, encode::sequence((
1792                 // Basic Constraints
1793                 self.basic_ca.map(|ca| {
1794                     encode_extension(
1795                         &oid::CE_BASIC_CONSTRAINTS, true,
1796                         encode::sequence(
1797                             if ca {
1798                                 Some(ca.encode())
1799                             }
1800                             else {
1801                                 None
1802                             }
1803                         )
1804                     )
1805                 }),
1806 
1807                 // Subject Key Identifier
1808                 encode_extension(
1809                     &oid::CE_SUBJECT_KEY_IDENTIFIER, false,
1810                     self.subject_key_identifier.encode_ref(),
1811                 ),
1812 
1813                 // Authority Key Identifier
1814                 self.authority_key_identifier.as_ref().map(|id| {
1815                     encode_extension(
1816                         &oid::CE_AUTHORITY_KEY_IDENTIFIER, false,
1817                         encode::sequence(id.encode_ref_as(Tag::CTX_0))
1818                     )
1819                 }),
1820 
1821                 // Key Usage
1822                 encode_extension(
1823                     &oid::CE_KEY_USAGE, true,
1824                     self.key_usage.encode()
1825                 ),
1826 
1827                 // Extended Key Usage
1828                 self.extended_key_usage.as_ref().map(|captured| {
1829                     encode_extension(
1830                         &oid::CE_EXTENDED_KEY_USAGE, false,
1831                         encode::sequence(captured)
1832                     )
1833                 }),
1834 
1835                 // CRL Distribution Points
1836                 self.crl_uri.as_ref().map(|uri| {
1837                     encode_extension(
1838                         &oid::CE_CRL_DISTRIBUTION_POINTS, false,
1839                         encode::sequence( // CRLDistributionPoints
1840                             encode::sequence( // DistributionPoint
1841                                 encode::sequence_as(Tag::CTX_0, // distrib.Pt.
1842                                     encode::sequence_as(Tag::CTX_0, // fullName
1843                                         uri.encode_general_name()
1844                                     )
1845                                 )
1846                             )
1847                         )
1848                     )
1849                 }),
1850 
1851                 // Authority Information Access
1852                 self.ca_issuer.as_ref().map(|uri| {
1853                     encode_extension(
1854                     &oid::PE_AUTHORITY_INFO_ACCESS, false,
1855                         encode::sequence(
1856                             encode::sequence((
1857                                 oid::AD_CA_ISSUERS.encode(),
1858                                 uri.encode_general_name()
1859                             ))
1860                         )
1861                     )
1862                 }),
1863 
1864                 // Subject Information Access
1865                 encode_extension(
1866                     &oid::PE_SUBJECT_INFO_ACCESS, false,
1867                     encode::sequence((
1868                         self.ca_repository.as_ref().map(|uri| {
1869                             encode::sequence((
1870                                 oid::AD_CA_REPOSITORY.encode(),
1871                                 uri.encode_general_name()
1872                             ))
1873                         }),
1874                         self.rpki_manifest.as_ref().map(|uri| {
1875                             encode::sequence((
1876                                 oid::AD_RPKI_MANIFEST.encode(),
1877                                 uri.encode_general_name()
1878                             ))
1879                         }),
1880                         self.signed_object.as_ref().map(|uri| {
1881                             encode::sequence((
1882                                 oid::AD_SIGNED_OBJECT.encode(),
1883                                 uri.encode_general_name()
1884                             ))
1885                         }),
1886                         self.rpki_notify.as_ref().map(|uri| {
1887                             encode::sequence((
1888                                 oid::AD_RPKI_NOTIFY.encode(),
1889                                 uri.encode_general_name()
1890                             ))
1891                         })
1892                     ))
1893                 ),
1894 
1895                 // Certificate Policies
1896                 encode_extension(
1897                     &oid::CE_CERTIFICATE_POLICIES, true,
1898                     encode::sequence(
1899                         encode::sequence(
1900                             self.overclaim.policy_id().encode()
1901                             // policyQualifiers sequence is optional
1902                         )
1903                     )
1904                 ),
1905 
1906                 // IP Resources
1907                 IpResources::encode_extension(
1908                     self.overclaim(),
1909                     self.v4_resources(),
1910                     self.v6_resources()
1911                 ),
1912 
1913                 // AS Resources
1914                 self.as_resources.encode_extension(self.overclaim)
1915             )))
1916         ))
1917     }
1918 }
1919 
1920 
1921 //------------ Helpers for Decoding and Encoding -----------------------------
1922 
1923 /// Parses a URI from the content of a GeneralNames sequence.
1924 ///
1925 /// ```text
1926 /// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1927 ///
1928 /// GeneralName ::= CHOICE {
1929 ///    ...
1930 ///    uniformResourceIdentifier       [6]     IA5String,
1931 ///    ... }
1932 /// ```
1933 ///
1934 /// Takes the first name for which the closure returns successfully. Ignores
1935 /// values where the closure produces an error. If there is more than one case
1936 /// where the closure returns successfully, that’s an error, too.
take_general_names_content<S: decode::Source, F, T, E>( cons: &mut decode::Constructed<S>, mut op: F ) -> Result<T, S::Err> where F: FnMut(Bytes) -> Result<T, E>1937 fn take_general_names_content<S: decode::Source, F, T, E>(
1938     cons: &mut decode::Constructed<S>,
1939     mut op: F
1940 ) -> Result<T, S::Err>
1941 where F: FnMut(Bytes) -> Result<T, E> {
1942     let mut res = None;
1943     while let Some(()) = cons.take_opt_value_if(Tag::CTX_6, |content| {
1944         let uri = Ia5String::from_content(content)?;
1945         if let Ok(uri) = op(uri.into_bytes()) {
1946             if res.is_some() {
1947                 xerr!(return Err(decode::Malformed.into()))
1948             }
1949             res = Some(uri)
1950         }
1951         Ok(())
1952     })? {}
1953     match res {
1954         Some(res) => Ok(res),
1955         None => xerr!(Err(decode::Malformed.into()))
1956     }
1957 }
1958 
take_general_name<S: decode::Source, F, T, E>( cons: &mut decode::Constructed<S>, mut op: F ) -> Result<Option<T>, S::Err> where F: FnMut(Bytes) -> Result<T, E>1959 fn take_general_name<S: decode::Source, F, T, E>(
1960     cons: &mut decode::Constructed<S>,
1961     mut op: F
1962 ) -> Result<Option<T>, S::Err>
1963 where F: FnMut(Bytes) -> Result<T, E> {
1964     cons.take_value_if(Tag::CTX_6, |content| {
1965         Ia5String::from_content(content).map(|uri| {
1966             op(uri.into_bytes()).ok()
1967         })
1968     })
1969 }
1970 
1971 /// Internal helper type for parsing Subject Information Access.
1972 #[derive(Clone, Debug, Default)]
1973 pub(crate) struct Sia {
1974     ca_repository: Option<uri::Rsync>,
1975     rpki_manifest: Option<uri::Rsync>,
1976     signed_object: Option<uri::Rsync>,
1977     rpki_notify: Option<uri::Https>,
1978 }
1979 
1980 impl Sia {
ca_repository(&self) -> Option<&uri::Rsync>1981     pub(crate) fn ca_repository(&self) -> Option<&uri::Rsync> {
1982         self.ca_repository.as_ref()
1983     }
rpki_manifest(&self) -> Option<&uri::Rsync>1984     pub(crate) fn rpki_manifest(&self) -> Option<&uri::Rsync> {
1985         self.rpki_manifest.as_ref()
1986     }
rpki_notify(&self) -> Option<&uri::Https>1987     pub(crate) fn rpki_notify(&self) -> Option<&uri::Https> {
1988         self.rpki_notify.as_ref()
1989     }
1990 }
1991 
1992 
1993 //------------ CertBuilder ---------------------------------------------------
1994 
1995 #[derive(Clone, Debug)]
1996 pub struct CertBuilder {
1997     //  The following lists how all the parts to go into the final certificate
1998     //  are to be generated. It also mentions all the parts that don’t need to
1999     //  be stored in the builder.
2000 
2001     //--- Certificate
2002     //
2003     //  tbsCertificate: see below,
2004     //  signatureAlgorithm and signature: generated when signing the final
2005     //     certificate
2006 
2007     //--- TBSCertificate
2008 
2009     //  Version.
2010     //
2011     //  This is always present and v3, which really is 2.
2012 
2013     /// Serial number.
2014     ///
2015     /// This is required for all certificates. The standard demands twenty
2016     /// digits, u128 gives us 38, so this should be fine.
2017     serial_number: u128,
2018 
2019     /// Signature.
2020     ///
2021     /// This is the signature algorithm and must be identical to the one used
2022     /// on the outer value. Thus, it needs to be set when constructing the
2023     /// certificate for signing.
2024 
2025     /// Issuer.
2026     ///
2027     /// This needs to be identical to the subject of the issuing certificate.
2028     /// It needs to be presented when creating the builder.
2029     issuer: Name,
2030 
2031     /// Validity.
2032     ///
2033     /// This needs to be present for all certificates.
2034     validity: Validity,
2035 
2036     /// Subject.
2037     ///
2038     /// This needs to be present for all certifications. In RPKI, we commonly
2039     /// derive the name from the public key of the certificate, so this is an
2040     /// option. If it is not set explicitly, we derive the name.
2041     subject: Option<Name>, // XXX NameBuilder?
2042 
2043     /// Subject Public Key Info
2044     ///
2045     /// This is required for all certificates. However, because we sometimes
2046     /// use one-off certificates that only receive their key info very late
2047     /// in the process, we won’t store the key info but take it as an
2048     /// argument for encoding.
2049 
2050     //  Issuer Unique ID, Subject Unique ID
2051     //
2052     //  These must not be present.
2053 
2054     //--- Extensions
2055 
2056     /// Basic Constraints
2057     ///
2058     /// Needs to be present and critical and the cA boolean set to true for
2059     /// a CA and TA certificate. We simply remember whether we are making a
2060     /// CA certificate here.
2061     ca: bool,
2062 
2063     //  Subject Key Identifier
2064     //
2065     //  Must be present and non-critical. It is the SHA1 of the BIT STRING
2066     //  of the Subject Public Key, so we take it from
2067     //  subject_public_key_info.
2068 
2069     /// Authority Key Identifier
2070     ///
2071     /// Must be present except in trust-anchor certificates and non-critical.
2072     /// It must contain the subject key identifier of issuing certificate.
2073     authority_key_identifier: Option<OctetString>,
2074 
2075     //  Key Usage.
2076     //
2077     //  Must be present and critical. For CA certificates, keyCertSign and
2078     //  CRLSign are set, for EE certificates, digitalSignature bit is set.
2079 
2080     //  Extended Key Usage
2081     //
2082     //  This is only allowed in router keys. For now, we will not support
2083     //  this.
2084 
2085     /// CRL Distribution Points
2086     ///
2087     /// Must be present and non-critical except in self-signed certificates.
2088     /// For RPKI it is very restricted and boils down to a list of URIs. Most
2089     /// likely, it will be exactly one. So for now, we allow at most one.
2090     crl_distribution: Option<uri::Rsync>,
2091 
2092     /// Authority Information Access
2093     ///
2094     /// Except for self-signed certificates, must be present and non-critical.
2095     /// There must be one rsync URI as a id-ad-caIssuer. Additional URIs may
2096     /// be present, but we don’t support that as of now.
2097     authority_info_access: Option<uri::Rsync>,
2098 
2099     //  Subject Information Access
2100     //
2101     //  Must be present and non-critical. There are essentially three
2102     //  access methods that may be present. id-ad-rpkiManifest points to the
2103     //  manifest of a CA, id-ad-signedObject points to the signed object of
2104     //  an EE certificate. id-ad-rpkiNotify points to the RRDP notification
2105     //  file of a CA. We only support one of each and simply add whatever is
2106     //  there.
2107 
2108     /// Subject Information Access of type `id-ad-caRepository`
2109     ca_repository: Option<uri::Rsync>,
2110 
2111     /// Subject Information Access of type `id-ad-rpkiManifest`
2112     rpki_manifest: Option<uri::Rsync>,
2113 
2114     /// Subject Information Access of type `id-ad-signedObject`
2115     signed_object: Option<uri::Rsync>,
2116 
2117     /// Subject Information Access of type `id-ad-rpkiNotify`
2118     rpki_notify: Option<uri::Https>,
2119 
2120     /// Certificate Policies
2121     ///
2122     /// This is chosen via the value of the overclaim mode,
2123     overclaim: Overclaim,
2124 
2125     /// IPv4 Resources
2126     ///
2127     /// One of the resources must be present. The IPv4 resources are part of
2128     /// the IP resources which, if present, it must be critical.
2129     v4_resources: IpResourcesBuilder,
2130 
2131     /// IPv6 Resources
2132     ///
2133     /// One of the resources must be present. The IPv4 resources are part of
2134     /// the IP resources which, if present, it must be critical.
2135     v6_resources: IpResourcesBuilder,
2136 
2137     /// AS Resources
2138     ///
2139     /// If present, it must be critical. One of the resources must be
2140     /// present.
2141     as_resources: AsResourcesBuilder,
2142 }
2143 
2144 impl CertBuilder {
new( serial_number: u128, issuer: Name, validity: Validity, ca: bool ) -> Self2145     pub fn new(
2146         serial_number: u128,
2147         issuer: Name,
2148         validity: Validity,
2149         ca: bool
2150     ) -> Self {
2151         CertBuilder {
2152             serial_number,
2153             issuer,
2154             validity,
2155             subject: None,
2156             ca,
2157             authority_key_identifier: None,
2158             crl_distribution: None,
2159             authority_info_access: None,
2160             ca_repository: None,
2161             rpki_manifest: None,
2162             signed_object: None,
2163             rpki_notify: None,
2164             overclaim: Overclaim::Refuse,
2165             v4_resources: IpResourcesBuilder::new(),
2166             v6_resources: IpResourcesBuilder::new(),
2167             as_resources: AsResourcesBuilder::new(),
2168         }
2169     }
2170 
subject(&mut self, name: Name) -> &mut Self2171     pub fn subject(&mut self, name: Name) -> &mut Self {
2172         self.subject = Some(name);
2173         self
2174     }
2175 
authority_key_identifier( &mut self, id: OctetString ) -> &mut Self2176     pub fn authority_key_identifier(
2177         &mut self, id: OctetString
2178     ) -> &mut Self {
2179         self.authority_key_identifier = Some(id);
2180         self
2181     }
2182 
crl_distribution(&mut self, uri: uri::Rsync) -> &mut Self2183     pub fn crl_distribution(&mut self, uri: uri::Rsync) -> &mut Self {
2184         self.crl_distribution = Some(uri);
2185         self
2186     }
2187 
authority_info_access(&mut self, uri: uri::Rsync) -> &mut Self2188     pub fn authority_info_access(&mut self, uri: uri::Rsync) -> &mut Self {
2189         self.authority_info_access = Some(uri);
2190         self
2191     }
2192 
ca_repository(&mut self, uri: uri::Rsync) -> &mut Self2193     pub fn ca_repository(&mut self, uri: uri::Rsync) -> &mut Self {
2194         self.ca_repository = Some(uri);
2195         self
2196     }
2197 
rpki_manifest(&mut self, uri: uri::Rsync) -> &mut Self2198     pub fn rpki_manifest(&mut self, uri: uri::Rsync) -> &mut Self {
2199         self.rpki_manifest = Some(uri);
2200         self
2201     }
2202 
signed_object(&mut self, uri: uri::Rsync) -> &mut Self2203     pub fn signed_object(&mut self, uri: uri::Rsync) -> &mut Self {
2204         self.signed_object = Some(uri);
2205         self
2206     }
2207 
rpki_notify(&mut self, uri: uri::Https) -> &mut Self2208     pub fn rpki_notify(&mut self, uri: uri::Https) -> &mut Self {
2209         self.rpki_notify = Some(uri);
2210         self
2211     }
2212 
overclaim(&mut self, overclaim: Overclaim) -> &mut Self2213     pub fn overclaim(&mut self, overclaim: Overclaim) -> &mut Self {
2214         self.overclaim = overclaim;
2215         self
2216     }
2217 
inherit_v4(&mut self) -> &mut Self2218     pub fn inherit_v4(&mut self) -> &mut Self {
2219         self.v4_resources.inherit();
2220         self
2221     }
2222 
inherit_v6(&mut self) -> &mut Self2223     pub fn inherit_v6(&mut self) -> &mut Self {
2224         self.v6_resources.inherit();
2225         self
2226     }
2227 
inherit_as(&mut self) -> &mut Self2228     pub fn inherit_as(&mut self) -> &mut Self {
2229         self.as_resources.inherit();
2230         self
2231     }
2232 
v4_blocks<F>(&mut self, build: F) -> &mut Self where F: FnOnce(&mut IpBlocksBuilder)2233     pub fn v4_blocks<F>(&mut self, build: F) -> &mut Self
2234     where F: FnOnce(&mut IpBlocksBuilder) {
2235         self.v4_resources.blocks(build);
2236         self
2237     }
2238 
v6_blocks<F>(&mut self, build: F) -> &mut Self where F: FnOnce(&mut IpBlocksBuilder)2239     pub fn v6_blocks<F>(&mut self, build: F) -> &mut Self
2240     where F: FnOnce(&mut IpBlocksBuilder) {
2241         self.v6_resources.blocks(build);
2242         self
2243     }
2244 
as_blocks<F>(&mut self, build: F) -> &mut Self where F: FnOnce(&mut AsBlocksBuilder)2245     pub fn as_blocks<F>(&mut self, build: F) -> &mut Self
2246     where F: FnOnce(&mut AsBlocksBuilder) {
2247         self.as_resources.blocks(build);
2248         self
2249     }
2250 
2251     /// Finalizes the certificate and returns an encoder for it.
encode<S: Signer>( self, signer: &S, key: &S::KeyId, alg: SignatureAlgorithm, public_key: &PublicKey, ) -> Result<impl encode::Values, SigningError<S::Error>>2252     pub fn encode<S: Signer>(
2253         self,
2254         signer: &S,
2255         key: &S::KeyId,
2256         alg: SignatureAlgorithm,
2257         public_key: &PublicKey,
2258     ) -> Result<impl encode::Values, SigningError<S::Error>> {
2259         let tbs_cert = self.encode_tbs_cert(alg, public_key);
2260         let (alg, signature) = signer.sign(key, alg, &tbs_cert)?.unwrap();
2261         Ok(encode::sequence((
2262             tbs_cert,
2263             alg.x509_encode(),
2264             BitString::new(0, signature).encode()
2265         )))
2266     }
2267 
encode_tbs_cert( mut self, alg: SignatureAlgorithm, public_key: &PublicKey, ) -> Captured2268     fn encode_tbs_cert(
2269         mut self,
2270         alg: SignatureAlgorithm,
2271         public_key: &PublicKey,
2272     ) -> Captured {
2273         if self.subject.is_none() {
2274             self.subject = Some(Name::from_pub_key(public_key))
2275         }
2276         Captured::from_values(Mode::Der, encode::sequence((
2277             encode::sequence_as(Tag::CTX_0, 2.encode()), // version
2278             self.serial_number.encode(),
2279             alg.x509_encode(),
2280             self.issuer.encode_ref(),
2281             self.validity.encode(),
2282             match self.subject.as_ref() {
2283                 Some(subject) => encode::Choice2::One(subject.encode_ref()),
2284                 None => {
2285                     encode::Choice2::Two(
2286                         public_key.encode_subject_name()
2287                     )
2288                 }
2289             },
2290             public_key.encode_ref(),
2291             // no issuerUniqueID, no subjectUniqueID
2292             encode::sequence_as(Tag::CTX_3, encode::sequence((
2293                 // Basic Constraints
2294                 if self.ca {
2295                     Some(Self::extension(
2296                         &oid::CE_BASIC_CONSTRAINTS, true,
2297                         encode::sequence(true.encode())
2298                     ))
2299                 }
2300                 else { None },
2301 
2302                 // Subject Key Identifier
2303                 Self::extension(
2304                     &oid::CE_SUBJECT_KEY_IDENTIFIER, false,
2305                     OctetString::encode_slice(
2306                         public_key.key_identifier()
2307                     )
2308                 ),
2309 
2310                 // Authority Key Identifier
2311                 self.authority_key_identifier.as_ref().map(|id| {
2312                     Self::extension(
2313                         &oid::CE_AUTHORITY_KEY_IDENTIFIER, false,
2314                         encode::sequence(id.encode_ref_as(Tag::CTX_0))
2315                     )
2316                 }),
2317 
2318                 // Key Usage
2319                 Self::extension(
2320                     &oid::CE_KEY_USAGE, true,
2321                     if self.ca {
2322                         // Bits 5 and 6 must be set.
2323                         b"\x01\x06".encode_as(Tag::BIT_STRING)
2324                     }
2325                     else {
2326                         // Bit 0 must be set.
2327                         b"\x07\x80".encode_as(Tag::BIT_STRING)
2328                     }
2329                 ),
2330 
2331                 // Extended Key Usage: currently not supported.
2332 
2333                 // CRL Distribution Points
2334                 self.crl_distribution.as_ref().map(|uri| {
2335                     Self::extension(
2336                         &oid::CE_CRL_DISTRIBUTION_POINTS, false,
2337                         encode::sequence( // CRLDistributionPoints
2338                             encode::sequence( // DistributionPoint
2339                                 encode::sequence_as(Tag::CTX_0, // distrib.Pt.
2340                                     encode::sequence_as(Tag::CTX_0, // fullName
2341                                         encode::sequence( // GeneralNames
2342                                             uri.encode_general_name()
2343                                         )
2344                                     )
2345                                 )
2346                             )
2347                         )
2348                     )
2349                 }),
2350 
2351                 // Authority Information Access
2352                 self.authority_info_access.as_ref().map(|uri| {
2353                     Self::extension(
2354                         &oid::PE_AUTHORITY_INFO_ACCESS, false,
2355                         encode::sequence(
2356                             encode::sequence((
2357                                 oid::AD_CA_ISSUERS.encode(),
2358                                 uri.encode_general_name()
2359                             ))
2360                         )
2361                     )
2362                 }),
2363 
2364                 // Subject Information Access
2365                 Self::extension(
2366                     &oid::PE_SUBJECT_INFO_ACCESS, false,
2367                     encode::sequence((
2368                         self.ca_repository.as_ref().map(|uri| {
2369                             encode::sequence((
2370                                 oid::AD_CA_REPOSITORY.encode(),
2371                                 uri.encode_general_name()
2372                             ))
2373                         }),
2374                         self.rpki_manifest.as_ref().map(|uri| {
2375                             encode::sequence((
2376                                 oid::AD_RPKI_MANIFEST.encode(),
2377                                 uri.encode_general_name()
2378                             ))
2379                         }),
2380                         self.signed_object.as_ref().map(|uri| {
2381                             encode::sequence((
2382                                 oid::AD_SIGNED_OBJECT.encode(),
2383                                 uri.encode_general_name()
2384                             ))
2385                         }),
2386                         self.rpki_notify.as_ref().map(|uri| {
2387                             encode::sequence((
2388                                 oid::AD_RPKI_NOTIFY.encode(),
2389                                 uri.encode_general_name()
2390                             ))
2391                         })
2392                     ))
2393                 ),
2394 
2395                 // Certificate Policies
2396                 Self::extension(
2397                     &oid::CE_CERTIFICATE_POLICIES, true,
2398                     encode::sequence(
2399                         encode::sequence(
2400                             oid::CP_IPADDR_ASNUMBER.encode()
2401                         )
2402                     )
2403                 ),
2404 
2405                 // IP Resources
2406                 IpResources::encode_extension(
2407                     self.overclaim,
2408                     &self.v4_resources.finalize(),
2409                     &self.v6_resources.finalize()
2410                 ),
2411 
2412                 // AS Resources
2413                 self.as_resources.finalize().encode_extension(
2414                     self.overclaim
2415                 ),
2416             )))
2417         )))
2418     }
2419 
extension<V: encode::Values>( oid: &'static ConstOid, critical: bool, content: V ) -> impl encode::Values2420     pub(crate) fn extension<V: encode::Values>(
2421         oid: &'static ConstOid,
2422         critical: bool,
2423         content: V
2424     ) -> impl encode::Values {
2425         encode::sequence((
2426             oid.encode(),
2427             critical.encode(),
2428             OctetString::encode_wrapped(Mode::Der, content)
2429         ))
2430     }
2431 }
2432 
2433 
2434 //------------ ResourceCert --------------------------------------------------
2435 
2436 /// A validated resource certificate.
2437 ///
2438 /// This differs from a normal [`Cert`] in that its IP and AS resources are
2439 /// resolved into concrete values.
2440 #[derive(Clone, Debug)]
2441 pub struct ResourceCert {
2442     /// The underlying resource certificate.
2443     cert: Cert,
2444 
2445     /// The resolved IPv4 resources.
2446     v4_resources: IpBlocks,
2447 
2448     /// The resolved IPv6 resources.
2449     v6_resources: IpBlocks,
2450 
2451     /// The resolved AS resources.
2452     as_resources: AsBlocks,
2453 
2454     /// The TAL this is based on.
2455     tal: Arc<TalInfo>,
2456 }
2457 
2458 impl ResourceCert {
2459     /// Returns a reference to the underlying certificate.
as_cert(&self) -> &Cert2460     pub fn as_cert(&self) -> &Cert {
2461         &self.cert
2462     }
2463 
2464     /// Returns a reference to the IPv4 resources of this certificate.
v4_resources(&self) -> &IpBlocks2465     pub fn v4_resources(&self) -> &IpBlocks {
2466         &self.v4_resources
2467     }
2468 
2469     /// Returns a reference to the IPv6 resources of this certificate.
v6_resources(&self) -> &IpBlocks2470     pub fn v6_resources(&self) -> &IpBlocks {
2471         &self.v6_resources
2472     }
2473 
2474     /// Returns a reference to the AS resources of this certificate.
as_resources(&self) -> &AsBlocks2475     pub fn as_resources(&self) -> &AsBlocks {
2476         &self.as_resources
2477     }
2478 
2479     /// Returns information about the TAL this certificate is based on.
tal(&self) -> &Arc<TalInfo>2480     pub fn tal(&self) -> &Arc<TalInfo> {
2481         &self.tal
2482     }
2483 
2484     /// Converts the certificate into its TAL info.
into_tal(self) -> Arc<TalInfo>2485     pub fn into_tal(self) -> Arc<TalInfo> {
2486         self.tal
2487     }
2488 }
2489 
2490 
2491 //--- Deref and AsRef
2492 
2493 impl ops::Deref for ResourceCert {
2494     type Target = Cert;
2495 
deref(&self) -> &Cert2496     fn deref(&self) -> &Cert {
2497         self.as_cert()
2498     }
2499 }
2500 
2501 impl AsRef<Cert> for ResourceCert {
as_ref(&self) -> &Cert2502     fn as_ref(&self) -> &Cert {
2503         self.as_cert()
2504     }
2505 }
2506 
2507 impl AsRef<TbsCert> for ResourceCert {
as_ref(&self) -> &TbsCert2508     fn as_ref(&self) -> &TbsCert {
2509         self.as_cert().as_ref()
2510     }
2511 }
2512 
2513 
2514 //------------ KeyUsage ------------------------------------------------------
2515 
2516 /// The allowed key usages of a resource certificate.
2517 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2518 pub enum KeyUsage {
2519     /// A CA certificate.
2520     Ca,
2521 
2522     /// An end-entity certificate.
2523     Ee,
2524 }
2525 
2526 impl KeyUsage {
2527     /// Returns a value encoder for the key usage.
encode(self) -> impl encode::Values2528     pub fn encode(self) -> impl encode::Values {
2529         let s = match self {
2530             KeyUsage::Ca => b"\x01\x06", // Bits 5 and 6
2531             KeyUsage::Ee => b"\x07\x80", // Bit 0
2532         };
2533         s.encode_as(Tag::BIT_STRING)
2534     }
2535 }
2536 
2537 
2538 //------------ Overclaim -----------------------------------------------------
2539 
2540 /// The overclaim mode for resource validation.
2541 ///
2542 /// In the original RPKI specification, a certificate becomes valid if it
2543 /// claims more resources than its issuer, a condition known as
2544 /// ‘overclaiming’. [RFC 8360] proposed an alternative approach where in this
2545 /// case the resources of the certificate are simply trimmed back to what the
2546 /// issuer certificate allows. This makes handling cases where a CA loses some
2547 /// resources easier.
2548 ///
2549 /// A certificate can choose to use the old or new method by using different
2550 /// OIDs for the certificate policy and the resource extensions.
2551 ///
2552 /// This type specifies which mode a certificate uses.
2553 ///
2554 /// [RFC 8380]: https://tools.ietf.org/html/rfc8360
2555 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2556 pub enum Overclaim {
2557     /// A certificate becomes invalid if it overclaims resources.
2558     Refuse,
2559 
2560     /// Overclaimed resources are trimmed to the by encompassed by the issuer.
2561     Trim,
2562 }
2563 
2564 impl Overclaim {
from_policy(oid: &Oid) -> Result<Self, decode::Error>2565     fn from_policy(oid: &Oid) -> Result<Self, decode::Error> {
2566         if oid == &oid::CP_IPADDR_ASNUMBER {
2567             Ok(Overclaim::Refuse)
2568         }
2569         else if oid == &oid::CP_IPADDR_ASNUMBER_V2 {
2570             Ok(Overclaim::Trim)
2571         }
2572         else {
2573             xerr!(Err(decode::Malformed))
2574         }
2575     }
2576 
from_ip_res(oid: &Oid) -> Option<Self>2577     fn from_ip_res(oid: &Oid) -> Option<Self> {
2578         if oid == &oid::PE_IP_ADDR_BLOCK {
2579             Some(Overclaim::Refuse)
2580         }
2581         else if oid == &oid::PE_IP_ADDR_BLOCK_V2 {
2582             Some(Overclaim::Trim)
2583         }
2584         else {
2585             None
2586         }
2587     }
2588 
from_as_res(oid: &Oid) -> Option<Self>2589     fn from_as_res(oid: &Oid) -> Option<Self> {
2590         if oid == &oid::PE_AUTONOMOUS_SYS_IDS {
2591             Some(Overclaim::Refuse)
2592         }
2593         else if oid == &oid::PE_AUTONOMOUS_SYS_IDS_V2 {
2594             Some(Overclaim::Trim)
2595         }
2596         else {
2597             None
2598         }
2599     }
2600 
policy_id(self) -> &'static ConstOid2601     pub fn policy_id(self) -> &'static ConstOid {
2602         match self {
2603             Overclaim::Refuse => &oid::CP_IPADDR_ASNUMBER,
2604             Overclaim::Trim => &oid::CP_IPADDR_ASNUMBER_V2
2605         }
2606     }
2607 
ip_res_id(self) -> &'static ConstOid2608     pub fn ip_res_id(self) -> &'static ConstOid {
2609         match self {
2610             Overclaim::Refuse => &oid::PE_IP_ADDR_BLOCK,
2611             Overclaim::Trim => &oid::PE_IP_ADDR_BLOCK_V2
2612         }
2613     }
2614 
as_res_id(self) -> &'static ConstOid2615     pub fn as_res_id(self) -> &'static ConstOid {
2616         match self {
2617             Overclaim::Refuse => &oid::PE_AUTONOMOUS_SYS_IDS,
2618             Overclaim::Trim => &oid::PE_AUTONOMOUS_SYS_IDS_V2
2619         }
2620     }
2621 }
2622 
2623 
2624 //============ Tests =========================================================
2625 
2626 #[cfg(test)]
2627 mod test {
2628     use super::*;
2629 
2630     #[test]
decode_and_inspect_certs()2631     fn decode_and_inspect_certs() {
2632         Cert::decode(
2633             include_bytes!("../../test-data/ta.cer").as_ref()
2634         ).unwrap().inspect_ta_at(
2635             true, Time::utc(2020, 11, 1, 12, 0, 0)
2636         ).unwrap();
2637         Cert::decode(
2638             include_bytes!("../../test-data/ca1.cer").as_ref()
2639         ).unwrap().inspect_ca_at(
2640             true, Time::utc(2020, 5, 1, 12, 0, 0)
2641         ).unwrap();
2642         Cert::decode(
2643             include_bytes!("../../test-data/router.cer").as_ref()
2644         ).unwrap().inspect_router_at(
2645             true, Time::utc(2020, 11, 1, 12, 0, 0)
2646         ).unwrap();
2647     }
2648 
2649     /// Tests that inconsistent algorithm encoding fail validation.
2650     ///
2651     /// Specifically, tests that a certificate with different encoding of
2652     /// the signature algorithm parameters (NULL value v. not present) in
2653     /// the outer certificate structure and inside the TbsCertificate will
2654     /// be rejected during the inspection step.
2655     #[test]
signature_algorithm_mismatch()2656     fn signature_algorithm_mismatch() {
2657         let roa = crate::repository::roa::Roa::decode(
2658             include_bytes!(
2659                 "../../test-data/example-ripe.roa"
2660             ).as_ref(),
2661             false
2662         ).unwrap();
2663         assert!(
2664             roa.cert().inspect_ee_at(
2665                 true, Time::utc(2020, 5, 1, 0, 0, 0)
2666             ).is_ok()
2667         );
2668 
2669         let mft = crate::repository::manifest::Manifest::decode(
2670             include_bytes!(
2671                 "../../test-data/signature-alg-mismatch.mft"
2672             ).as_ref(),
2673             false
2674         ).unwrap();
2675         assert!(
2676             mft.cert().inspect_ee_at(
2677                 true, Time::utc(2020, 5, 1, 0, 0, 0)
2678             ).is_err()
2679         );
2680     }
2681 
2682     #[test]
2683     #[cfg(feature = "serde")]
serde_cert()2684     fn serde_cert() {
2685         let der = include_bytes!("../../test-data/ta.cer");
2686         let cert = Cert::decode(Bytes::from_static(der)).unwrap();
2687 
2688         let serialize = serde_json::to_string(&cert).unwrap();
2689         let des_cert: Cert = serde_json::from_str(&serialize).unwrap();
2690 
2691         assert_eq!(cert.to_captured().into_bytes(), des_cert.to_captured().into_bytes());
2692 
2693     }
2694 }
2695 
2696 #[cfg(all(test, feature="softkeys"))]
2697 mod signer_test {
2698     use std::str::FromStr;
2699     use crate::repository::cert::Cert;
2700     use crate::repository::crypto::PublicKeyFormat;
2701     use crate::repository::crypto::softsigner::OpenSslSigner;
2702     use crate::repository::resources::{AsId, Prefix};
2703     use crate::repository::tal::TalInfo;
2704     use super::*;
2705 
2706 
2707     #[test]
build_ta_cert()2708     fn build_ta_cert() {
2709         let signer = OpenSslSigner::new();
2710         let key = signer.create_key(PublicKeyFormat::Rsa).unwrap();
2711         let pubkey = signer.get_key_info(&key).unwrap();
2712         let uri = uri::Rsync::from_str("rsync://example.com/m/p").unwrap();
2713         let mut cert = TbsCert::new(
2714             12u64.into(), pubkey.to_subject_name(),
2715             Validity::from_secs(86400), None, pubkey, KeyUsage::Ca,
2716             Overclaim::Trim
2717         );
2718         cert.set_basic_ca(Some(true));
2719         cert.set_ca_repository(Some(uri.clone()));
2720         cert.set_rpki_manifest(Some(uri));
2721         cert.build_v4_resource_blocks(|b| b.push(Prefix::new(0, 0)));
2722         cert.build_v6_resource_blocks(|b| b.push(Prefix::new(0, 0)));
2723         cert.build_as_resource_blocks(|b| b.push((AsId::MIN, AsId::MAX)));
2724         let cert = cert.into_cert(&signer, &key).unwrap().to_captured();
2725         let cert = Cert::decode(cert.as_slice()).unwrap();
2726         let talinfo = TalInfo::from_name("foo".into()).into_arc();
2727         cert.validate_ta(talinfo, true).unwrap();
2728     }
2729 }
2730 
2731 
2732