1 //! Resource Tagged Attestations.
2 //!
3 //! Resource Tagged Attestations attaching signed attestations of ownership of
4 //! resources referred to by a document. This is currently an IETF draft,
5 //! see [draft-michaelson-rpki-rta] for details.
6 //!
7 //! Current limitations:
8 //!
9 //! * Resources are read in a rather relaxed way: they can be unordered and
10 //!   overlapping. This happens even if the strict flag is set.
11 //!
12 //! draft-michaelson-rpki-rta: https://tools.ietf.org/html/draft-michaelson-rpki-rta
13 
14 use std::ops;
15 use bcder::{decode, encode};
16 use bcder::{Captured, Mode, OctetString, Tag};
17 use bcder::encode::{PrimitiveContent, Values};
18 use bcder::string::OctetStringSource;
19 use bcder::xerr;
20 use bytes::Bytes;
21 use super::oid;
22 use super::cert::{Cert, Overclaim, ResourceCert};
23 use super::crl::Crl;
24 use super::crypto:: {
25     Digest, DigestAlgorithm, KeyIdentifier, Signature, SignatureAlgorithm,
26     Signer, SigningError
27 };
28 use super::resources::{
29     AddressFamily, AsBlock, AsBlocks, AsBlocksBuilder, IpBlock, IpBlocks,
30     IpBlocksBuilder,
31 };
32 use super::sigobj::{MessageDigest, SignedAttrs};
33 use super::tal::Tal;
34 use super::x509::{Time, ValidationError};
35 
36 
37 //------------ Rta -----------------------------------------------------------
38 
39 #[derive(Clone, Debug)]
40 pub struct Rta {
41     signed: MultiSignedObject,
42     content: ResourceTaggedAttestation,
43 }
44 
45 impl Rta {
content(&self) -> &ResourceTaggedAttestation46     pub fn content(&self) -> &ResourceTaggedAttestation {
47         &self.content
48     }
49 
decode<S: decode::Source>( source: S, strict: bool ) -> Result<Self, S::Err>50     pub fn decode<S: decode::Source>(
51         source: S, strict: bool
52     ) -> Result<Self, S::Err> {
53         let signed = MultiSignedObject::decode(source, strict)?;
54         let content = signed.decode_content(|cons| {
55             ResourceTaggedAttestation::take_from(cons)
56         })?;
57         Ok(Rta { signed, content })
58     }
59 
60     /// Returns a value encoder for a reference to a ROA.
encode_ref(&self) -> impl encode::Values + '_61     pub fn encode_ref(&self) -> impl encode::Values + '_ {
62         self.signed.encode_ref()
63     }
64 
65     /// Returns a DER encoded Captured for this ROA.
to_captured(&self) -> Captured66     pub fn to_captured(&self) -> Captured {
67         self.encode_ref().to_captured(Mode::Der)
68     }
69 }
70 
71 
72 //--- Deref and AsRef
73 
74 impl ops::Deref for Rta {
75     type Target = ResourceTaggedAttestation;
76 
deref(&self) -> &Self::Target77     fn deref(&self) -> &Self::Target {
78         self.content()
79     }
80 }
81 
82 impl AsRef<ResourceTaggedAttestation> for Rta {
as_ref(&self) -> &ResourceTaggedAttestation83     fn as_ref(&self) -> &ResourceTaggedAttestation {
84         self.content()
85     }
86 }
87 
88 
89 //------------ ResourceTaggedAttestation -------------------------------------
90 
91 #[derive(Clone, Debug)]
92 pub struct ResourceTaggedAttestation {
93     subject_keys: Vec<KeyIdentifier>,
94 
95     /// AS Resources
96     as_resources: AsBlocks,
97 
98     /// IP Resources for the IPv4 address family.
99     v4_resources: IpBlocks,
100 
101     /// IP Resources for the IPv6 address family.
102     v6_resources: IpBlocks,
103 
104     digest_algorithm: DigestAlgorithm,
105 
106     message_digest: MessageDigest,
107 }
108 
109 impl ResourceTaggedAttestation {
subject_keys(&self) -> &[KeyIdentifier]110     pub fn subject_keys(&self) -> &[KeyIdentifier] {
111         &self.subject_keys
112     }
113 
as_resources(&self) -> &AsBlocks114     pub fn as_resources(&self) -> &AsBlocks {
115         &self.as_resources
116     }
117 
v4_resources(&self) -> &IpBlocks118     pub fn v4_resources(&self) -> &IpBlocks {
119         &self.v4_resources
120     }
121 
v6_resources(&self) -> &IpBlocks122     pub fn v6_resources(&self) -> &IpBlocks {
123         &self.v6_resources
124     }
125 
digest_algorithm(&self) -> DigestAlgorithm126     pub fn digest_algorithm(&self) -> DigestAlgorithm {
127         self.digest_algorithm
128     }
129 
message_digest(&self) -> &MessageDigest130     pub fn message_digest(&self) -> &MessageDigest {
131         &self.message_digest
132     }
133 }
134 
135 impl ResourceTaggedAttestation {
take_from<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<Self, S::Err>136     fn take_from<S: decode::Source>(
137         cons: &mut decode::Constructed<S>
138     ) -> Result<Self, S::Err> {
139         cons.take_sequence(|cons| {
140             cons.take_opt_constructed_if(Tag::CTX_0, |c| c.skip_u8_if(0))?;
141             let subject_keys = Self::take_subject_keys_from(cons)?;
142             let (v4res, v6res, asres) = Self::take_resources_from(cons)?;
143             let alg = DigestAlgorithm::take_from(cons)?;
144             let digest = OctetString::take_from(cons)?;
145             Ok(ResourceTaggedAttestation {
146                 subject_keys,
147                 v4_resources: v4res,
148                 v6_resources: v6res,
149                 as_resources: asres,
150                 digest_algorithm: alg,
151                 message_digest: digest.into(),
152             })
153         })
154     }
155 
take_subject_keys_from<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<Vec<KeyIdentifier>, S::Err>156     fn take_subject_keys_from<S: decode::Source>(
157         cons: &mut decode::Constructed<S>
158     ) -> Result<Vec<KeyIdentifier>, S::Err> {
159         cons.take_set(|cons| {
160             let mut res = Vec::new();
161             while let Some(id) = KeyIdentifier::take_opt_from(cons)? {
162                 res.push(id)
163             }
164             Ok(res)
165         })
166     }
167 
take_resources_from<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<(IpBlocks, IpBlocks, AsBlocks), S::Err>168     fn take_resources_from<S: decode::Source>(
169         cons: &mut decode::Constructed<S>
170     ) -> Result<(IpBlocks, IpBlocks, AsBlocks), S::Err> {
171         cons.take_sequence(|cons| {
172             let asres = cons.take_opt_constructed_if(Tag::CTX_0, |cons| {
173                 AsBlocks::take_from(cons)
174             })?;
175 
176             let mut v4 = None;
177             let mut v6 = None;
178             cons.take_opt_constructed_if(Tag::CTX_1, |cons| {
179                 cons.take_sequence(|cons| {
180                     while let Some(()) = cons.take_opt_sequence(|cons| {
181                         match AddressFamily::take_from(cons)? {
182                             AddressFamily::Ipv4 => {
183                                 if v4.is_some() {
184                                     xerr!(return Err(decode::Malformed.into()));
185                                 }
186                                 v4 = Some(IpBlocks::take_from_with_family(
187                                     cons, AddressFamily::Ipv4
188                                 )?);
189                             }
190                             AddressFamily::Ipv6 => {
191                                 if v6.is_some() {
192                                     xerr!(return Err(decode::Malformed.into()));
193                                 }
194                                 v6 = Some(IpBlocks::take_from_with_family(
195                                     cons, AddressFamily::Ipv6
196                                 )?);
197                             }
198                         }
199                         Ok(())
200                     })? { }
201                     Ok(())
202                 })
203             })?;
204 
205             if asres.is_none() && v4.is_none() && v6.is_none() {
206                 xerr!(return Err(decode::Malformed.into()));
207             }
208             Ok((
209                 v4.unwrap_or_default(),
210                 v6.unwrap_or_default(),
211                 asres.unwrap_or_default(),
212             ))
213         })
214     }
215 
encode_ref(&self) -> impl encode::Values + '_216     pub fn encode_ref(&self) -> impl encode::Values + '_ {
217         encode::sequence((
218             // version is DEFAULT
219             encode::set(
220                 encode::iter(self.subject_keys.iter().map(|item| {
221                     item.encode_ref()
222                 }))
223             ),
224             encode::sequence((
225                 self.encode_as_resources(),
226                 self.encode_ip_resources(),
227             )),
228             self.digest_algorithm.encode(),
229             self.message_digest.encode_ref()
230         ))
231     }
232 
encode_as_resources(&self) -> impl encode::Values + '_233     fn encode_as_resources(&self) -> impl encode::Values + '_ {
234         if self.as_resources.is_empty() {
235             None
236         }
237         else {
238             Some(encode::sequence_as(Tag::CTX_0,
239                 encode::sequence(
240                     self.as_resources.encode_ref()
241                 )
242             ))
243         }
244     }
245 
encode_ip_resources(&self) -> impl encode::Values + '_246     fn encode_ip_resources(&self) -> impl encode::Values + '_ {
247         if self.v4_resources.is_empty() && self.v6_resources.is_empty() {
248             return None
249         }
250         Some(encode::sequence_as(Tag::CTX_1,
251             encode::sequence((
252                 self.v4_resources.encode_family(AddressFamily::Ipv4),
253                 self.v6_resources.encode_family(AddressFamily::Ipv6),
254             ))
255         ))
256     }
257 
to_bytes(&self) -> Bytes258     fn to_bytes(&self) -> Bytes {
259         self.encode_ref().to_captured(Mode::Der).into_bytes()
260     }
261 }
262 
263 
264 //------------ MultiSignedObject ---------------------------------------------
265 
266 /// The flavour of a signed object used for RTAs.
267 #[derive(Clone, Debug)]
268 pub struct MultiSignedObject {
269     digest_algorithm: DigestAlgorithm,
270     content: OctetString,
271     certificates: Vec<Cert>,
272     crls: Vec<Crl>,
273     signer_infos: Vec<SignerInfo>,
274 }
275 
276 impl MultiSignedObject {
277     /// Returns a reference to the object’s content.
content(&self) -> &OctetString278     pub fn content(&self) -> &OctetString {
279         &self.content
280     }
281 
282     /// Decodes the object’s content.
decode_content<F, T>(&self, op: F) -> Result<T, decode::Error> where F: FnOnce(&mut decode::Constructed<OctetStringSource>) -> Result<T, decode::Error>283     pub fn decode_content<F, T>(&self, op: F) -> Result<T, decode::Error>
284     where F: FnOnce(&mut decode::Constructed<OctetStringSource>)
285                     -> Result<T, decode::Error> {
286         Mode::Der.decode(self.content.to_source(), op)
287     }
288 }
289 
290 impl MultiSignedObject {
decode<S: decode::Source>( source: S, strict: bool ) -> Result<Self, S::Err>291     pub fn decode<S: decode::Source>(
292         source: S, strict: bool
293     ) -> Result<Self, S::Err> {
294         Mode::Der.decode(source, |cons| Self::take_from(cons, strict))
295     }
296 
take_from<S: decode::Source>( cons: &mut decode::Constructed<S>, strict: bool ) -> Result<Self, S::Err>297     pub fn take_from<S: decode::Source>(
298         cons: &mut decode::Constructed<S>, strict: bool
299     ) -> Result<Self, S::Err> {
300         cons.take_sequence(|cons| {
301             oid::SIGNED_DATA.skip_if(cons)?; // contentType
302             cons.take_constructed_if(Tag::CTX_0, |cons| { // content
303                 cons.take_sequence(|cons| { // SignedData
304                     cons.skip_u8_if(3)?; // version -- must be 3
305                     let digest_algorithm =
306                         DigestAlgorithm::take_set_from(cons)?;
307                     let content = cons.take_sequence(|cons| {
308                         // encapContentInfo
309                         oid::CT_RESOURCE_TAGGED_ATTESTATION.skip_if(cons)?;
310                         cons.take_constructed_if(
311                             Tag::CTX_0,
312                             OctetString::take_from
313                         )
314                     })?;
315                     let certificates = Self::take_certificates(cons, strict)?;
316                     let crls = Self::take_crls(cons, strict)?;
317                     let signer_infos = Self::take_signer_infos(cons, strict)?;
318 
319                     Ok(MultiSignedObject {
320                         digest_algorithm,
321                         content,
322                         certificates,
323                         crls,
324                         signer_infos,
325                     })
326                 })
327             })
328         })
329     }
330 
take_certificates<S: decode::Source>( cons: &mut decode::Constructed<S>, _strict: bool ) -> Result<Vec<Cert>, S::Err>331     fn take_certificates<S: decode::Source>(
332         cons: &mut decode::Constructed<S>, _strict: bool
333     ) -> Result<Vec<Cert>, S::Err> {
334         cons.take_constructed_if(Tag::CTX_0, |cons| {
335             let mut certificates = Vec::new();
336             while let Some(cert) = Cert::take_opt_from(cons)? {
337                 certificates.push(cert);
338             }
339             Ok(certificates)
340         })
341     }
342 
take_crls<S: decode::Source>( cons: &mut decode::Constructed<S>, _strict: bool ) -> Result<Vec<Crl>, S::Err>343     fn take_crls<S: decode::Source>(
344         cons: &mut decode::Constructed<S>, _strict: bool
345     ) -> Result<Vec<Crl>, S::Err> {
346         cons.take_opt_constructed_if(Tag::CTX_1, |cons| {
347             let mut crls = Vec::new();
348             while let Some(crl) = Crl::take_opt_from(cons)? {
349                 crls.push(crl);
350             }
351             Ok(crls)
352         }).map(|item| item.unwrap_or_default())
353     }
354 
take_signer_infos<S: decode::Source>( cons: &mut decode::Constructed<S>, _strict: bool ) -> Result<Vec<SignerInfo>, S::Err>355     fn take_signer_infos<S: decode::Source>(
356         cons: &mut decode::Constructed<S>, _strict: bool
357     ) -> Result<Vec<SignerInfo>, S::Err> {
358         cons.take_set(|cons| {
359             let mut infos = Vec::new();
360             while let Some(info) = SignerInfo::take_opt_from(cons)? {
361                 infos.push(info);
362             }
363             Ok(infos)
364         })
365     }
366 
367     /// Returns a value encoder for a reference to a signed object.
encode_ref(&self) -> impl encode::Values + '_368     pub fn encode_ref(&self) -> impl encode::Values + '_ {
369         encode::sequence((
370             oid::SIGNED_DATA.encode(), // contentType
371             encode::sequence_as(Tag::CTX_0, // content
372                 encode::sequence((
373                     3u8.encode(), // version
374                     self.digest_algorithm.encode_set(), // digestAlgorithms
375                     encode::sequence(( // encapContentInfo
376                         oid::CT_RESOURCE_TAGGED_ATTESTATION.encode(),
377                         encode::sequence_as(Tag::CTX_0,
378                             self.content.encode_ref()
379                         ),
380                     )),
381                     encode::sequence_as(Tag::CTX_0, // certificates
382                         encode::iter(self.certificates.iter().map(|item| {
383                             item.encode_ref()
384                         }))
385                     ),
386                     if self.crls.is_empty() {
387                         None
388                     }
389                     else {
390                         Some(encode::sequence_as(Tag::CTX_1, // crls
391                             encode::iter(self.crls.iter().map(|item| {
392                                 item.encode_ref()
393                             }))
394                         ))
395                     },
396                     encode::set(
397                         encode::iter(self.signer_infos.iter().map(|item| {
398                             item.encode_ref()
399                         }))
400                     )
401                 )),
402             )
403         ))
404     }
405 }
406 
407 
408 //------------ SignerInfo ----------------------------------------------------
409 
410 /// A single SignerInfo of a signed object.
411 #[derive(Clone, Debug)]
412 pub struct SignerInfo {
413     sid: KeyIdentifier,
414     digest_algorithm: DigestAlgorithm,
415     signed_attrs: SignedAttrs,
416     signature: Signature,
417 
418     //--- SignedAttributes
419     //
420     message_digest: MessageDigest,
421     signing_time: Option<Time>,
422     binary_signing_time: Option<u64>,
423 }
424 
425 impl SignerInfo {
426     /// Returns the signing time if available.
signing_time(&self) -> Option<Time>427     pub fn signing_time(&self) -> Option<Time> {
428         self.signing_time
429     }
430 
431     /// Returns the binary signing time if available.
binary_signing_time(&self) -> Option<u64>432     pub fn binary_signing_time(&self) -> Option<u64> {
433         self.binary_signing_time
434     }
435 
take_opt_from<S: decode::Source>( cons: &mut decode::Constructed<S>, ) -> Result<Option<Self>, S::Err>436     pub fn take_opt_from<S: decode::Source>(
437         cons: &mut decode::Constructed<S>,
438     ) -> Result<Option<Self>, S::Err> {
439         cons.take_opt_sequence(|cons| {
440             cons.skip_u8_if(3)?;
441             let sid = cons.take_value_if(
442                 Tag::CTX_0, |content| {
443                     KeyIdentifier::from_content(content)
444                 }
445             )?;
446             let alg = DigestAlgorithm::take_from(cons)?;
447             let attrs = SignedAttrs::take_from(cons)?;
448             if attrs.2 != oid::CT_RESOURCE_TAGGED_ATTESTATION {
449                 return Err(decode::Malformed.into())
450             }
451             let signature = Signature::new(
452                 SignatureAlgorithm::cms_take_from(cons)?,
453                 OctetString::take_from(cons)?.into_bytes()
454             );
455             // no unsignedAttributes
456             Ok(SignerInfo {
457                 sid,
458                 digest_algorithm: alg,
459                 signed_attrs: attrs.0,
460                 signature,
461                 message_digest: attrs.1,
462                 signing_time: attrs.3,
463                 binary_signing_time: attrs.4
464             })
465         })
466     }
467 
encode_ref(&self) -> impl encode::Values + '_468     pub fn encode_ref(&self) -> impl encode::Values + '_ {
469         encode::sequence((
470             3u8.encode(), // version
471             self.sid.encode_ref_as(Tag::CTX_0),
472             self.digest_algorithm.encode(), // digestAlgorithm
473             self.signed_attrs.encode_ref(), // signedAttrs
474             self.signature.algorithm().cms_encode(),
475                                         // signatureAlgorithm
476             OctetString::encode_slice( // signature
477                 self.signature.value().as_ref()
478             ),
479             // unsignedAttrs omitted
480         ))
481     }
482 }
483 
484 
485 //------------ Validation ----------------------------------------------------
486 
487 #[derive(Clone, Debug)]
488 pub struct Validation<'a> {
489     /// The RTA object we are validating.
490     rta: &'a Rta,
491 
492     /// The validation chains we need to validate.
493     chains: Vec<Chain<'a>>,
494 
495     /// Are we doing strict validation?
496     strict: bool,
497 
498     /// What time is it, Geoff Peterson?
499     now: Time,
500 }
501 
502 impl<'a> Validation<'a> {
new( rta: &'a Rta, strict: bool ) -> Result<Self, ValidationError>503     pub fn new(
504         rta: &'a Rta, strict: bool
505     ) -> Result<Self, ValidationError> {
506         Self::new_at(rta, strict, Time::now())
507     }
508 
new_at( rta: &'a Rta, strict: bool, now: Time, ) -> Result<Self, ValidationError>509     pub fn new_at(
510         rta: &'a Rta, strict: bool, now: Time,
511     ) -> Result<Self, ValidationError> {
512         // Get a vec with options of refs to the CRLs. Whenever we used a CRL
513         // in a CA, we take it out. Thus, at the end we need to have all
514         // `None` in the vec.
515         let mut crls: Vec<_> = rta.signed.crls.iter().map(Some).collect();
516 
517         // Ditto for the subject keys included with the content.
518         let mut keys: Vec<_> = rta.content.subject_keys.iter().map(|key| {
519             Some(*key)
520         }).collect();
521 
522         // Calculate the digest of the content.
523         let digest = {
524             let mut context = rta.signed.digest_algorithm.start();
525             rta.signed.content.iter().for_each(|x| context.update(x));
526             context.finish()
527         };
528 
529         // Process all certificates. CA certificates go into the CA vec and
530         // EE certificates go into a temporary option-vec which we use when
531         // creating chains from signer-infos later.
532         let mut cas = Vec::new();
533         let mut ees = Vec::new();
534         for cert in &rta.signed.certificates {
535             if cert.basic_ca().is_none() {
536                 cert.inspect_detached_ee_at(strict, now)?;
537                 ees.push(Some(cert));
538             }
539             else {
540                 cas.push(Ca::new(cert, &mut crls, strict, now)?);
541             }
542         }
543 
544         let mut chains = Vec::new();
545         for info in &rta.signed.signer_infos {
546             chains.push(
547                 Chain::new(info, &digest, &mut keys, &mut ees)?
548             )
549         }
550 
551         // All subject keys need to have been used.
552         if keys.iter().any(|item| item.is_some()) {
553             xerr!(return Err(ValidationError))
554         }
555 
556         // All CRLs need to have been used.
557         if crls.iter().any(|item| item.is_some()) {
558             xerr!(return Err(ValidationError))
559         }
560 
561         // All EE certificates have to have been used.
562         if ees.iter().any(|item| item.is_some()) {
563             xerr!(return Err(ValidationError))
564         }
565 
566         // Create the object and advance the chains using the CA certificates
567         // we have.
568         let mut res = Validation { rta, chains, strict, now };
569         res.advance_chains(&mut cas)?;
570 
571         // All the CA certificates have to have been used.
572         if cas.iter().any(|item| !item.used) {
573             xerr!(return Err(ValidationError))
574         }
575 
576         // Hurray!
577         Ok(res)
578     }
579 
advance_chains( &mut self, cas: &mut [Ca<'a>] ) -> Result<(), ValidationError>580     fn advance_chains(
581         &mut self, cas: &mut [Ca<'a>]
582     ) -> Result<(), ValidationError> {
583         for chain in &mut self.chains {
584             chain.advance(cas, self.strict)?;
585         }
586         Ok(())
587     }
588 
supply_tal(&mut self, tal: &Tal) -> Result<bool, ValidationError>589     pub fn supply_tal(&mut self, tal: &Tal) -> Result<bool, ValidationError> {
590         let mut done = true;
591         for chain in &mut self.chains {
592             if !chain.supply_tal(tal, self.strict, self.now)? {
593                 done = false
594             }
595         }
596         Ok(done)
597     }
598 
supply_ca( &mut self, ca: &ResourceCert ) -> Result<bool, ValidationError>599     pub fn supply_ca(
600         &mut self, ca: &ResourceCert
601     ) -> Result<bool, ValidationError> {
602         let mut done = true;
603         for chain in &mut self.chains {
604             if !chain.supply_ca(ca, self.strict, self.now)? {
605                 done = false
606             }
607         }
608         Ok(done)
609     }
610 
finalize( self ) -> Result<&'a ResourceTaggedAttestation, ValidationError>611     pub fn finalize(
612         self
613     ) -> Result<&'a ResourceTaggedAttestation, ValidationError> {
614         let mut asn = AsBlocksBuilder::new();
615         let mut v4 = IpBlocksBuilder::new();
616         let mut v6 = IpBlocksBuilder::new();
617 
618         for chain in &self.chains {
619             chain.finalize(&mut asn, &mut v4, &mut v6)?;
620         }
621 
622         let asn = asn.finalize();
623         let v4 = v4.finalize();
624         let v6 = v6.finalize();
625 
626         if asn != self.rta.content.as_resources
627             || v4 != self.rta.content.v4_resources
628             || v6 != self.rta.content.v6_resources
629         {
630             return Err(ValidationError)
631         }
632 
633         Ok(self.rta)
634     }
635 }
636 
637 
638 //------------ Ca ------------------------------------------------------------
639 
640 #[derive(Clone, Debug)]
641 struct Ca<'a> {
642     cert: &'a Cert,
643     crl: &'a Crl,
644     used: bool,
645 }
646 
647 impl<'a> Ca<'a> {
new( cert: &'a Cert, crls: &mut [Option<&'a Crl>], strict: bool, now: Time, ) -> Result<Self, ValidationError>648     fn new(
649         cert: &'a Cert,
650         crls: &mut [Option<&'a Crl>],
651         strict: bool, now: Time,
652     ) -> Result<Self, ValidationError> {
653         cert.inspect_ca_at(strict, now)?;
654         Ok(Ca {
655             cert,
656             crl: Self::find_crl(cert, crls)?,
657             used: false
658         })
659     }
660 
find_crl<'c>( cert: &Cert, crls: &mut [Option<&'c Crl>] ) -> Result<&'c Crl, ValidationError>661     fn find_crl<'c>(
662         cert: &Cert, crls: &mut [Option<&'c Crl>]
663     ) -> Result<&'c Crl, ValidationError> {
664         for crl in crls {
665             match crl.as_ref() {
666                 Some(crl) => {
667                     if *crl.authority_key_identifier()
668                         != cert.subject_key_identifier()
669                     {
670                         continue
671                     }
672                     if crl.validate(cert.subject_public_key_info()).is_err() {
673                         continue
674                     }
675                 }
676                 None => continue
677             }
678             return Ok(crl.take().unwrap())
679         }
680         Err(ValidationError)
681     }
682 }
683 
684 
685 //------------ Chain ---------------------------------------------------------
686 
687 #[derive(Clone, Debug)]
688 struct Chain<'a> {
689     /// The topmost certificate of the path.
690     cert: &'a Cert,
691 
692     /// The resources of the topmost cert.
693     cert_resources: CertResources,
694 
695     /// The resources of the entire path.
696     chain_resources: CertResources,
697 
698     /// Has the chain been validated?
699     validated: bool,
700 }
701 
702 impl<'a> Chain<'a> {
703     //--- new and helpers
704 
new( info: &SignerInfo, digest: &Digest, keys: &mut [Option<KeyIdentifier>], ees: &mut [Option<&'a Cert>], ) -> Result<Self, ValidationError>705     fn new(
706         info: &SignerInfo,
707         digest: &Digest,
708         keys: &mut [Option<KeyIdentifier>],
709         ees: &mut [Option<&'a Cert>],
710     ) -> Result<Self, ValidationError> {
711         // Find and removed sid in keys.
712         match keys.iter_mut().find(|item| **item == Some(info.sid)) {
713             Some(item) => *item = None,
714             None => xerr!(return Err(ValidationError))
715         }
716 
717         // Verify the message digest attribute
718         if digest.as_ref() != info.message_digest.as_ref() {
719             return xerr!(Err(ValidationError))
720         }
721 
722         // Find th EE cert that signed this signer info.
723         let ee = Self::find_cert(info, ees)?;
724 
725         let resources = CertResources::new(ee);
726         Ok(Chain {
727             cert: ee,
728             cert_resources: resources.clone(),
729             chain_resources: resources,
730             validated: false
731         })
732     }
733 
find_cert( info: &SignerInfo, ees: &mut [Option<&'a Cert>] ) -> Result<&'a Cert, ValidationError>734     fn find_cert(
735         info: &SignerInfo,
736         ees: &mut [Option<&'a Cert>]
737     ) -> Result<&'a Cert, ValidationError> {
738         let msg = info.signed_attrs.encode_verify();
739         for item in ees {
740             if let Some(cert) = *item {
741                 if cert.subject_key_identifier() != info.sid {
742                     continue
743                 }
744                 if cert.subject_public_key_info().verify(
745                     &msg,
746                     &info.signature
747                 ).is_err() {
748                     continue
749                 }
750                 *item = None;
751                 return Ok(cert)
752             }
753 
754         }
755         xerr!(Err(ValidationError))
756     }
757 
758     //--- advance and helpers
759 
advance( &mut self, cas: &mut [Ca<'a>], strict: bool, ) -> Result<(), ValidationError>760     fn advance(
761         &mut self,
762         cas: &mut [Ca<'a>],
763         strict: bool,
764     ) -> Result<(), ValidationError> {
765         while let Some(ca) = self.find_ca(cas, strict)? {
766             self.apply_ca(ca)?;
767             ca.used = true;
768         }
769         Ok(())
770     }
771 
find_ca<'c>( &self, cas: &'c mut [Ca<'a>], strict: bool, ) -> Result<Option<&'c mut Ca<'a>>, ValidationError>772     fn find_ca<'c>(
773         &self,
774         cas: &'c mut [Ca<'a>],
775         strict: bool,
776     ) -> Result<Option<&'c mut Ca<'a>>, ValidationError> {
777         // If we don’t have an authority key identifier on the cert, it is
778         // self-signed and we are done. If we do have one and it is the same
779         // as the subject key identifier, it is self-signed, too.
780         let aki = match self.cert.authority_key_identifier() {
781             Some(aki) if aki == self.cert.subject_key_identifier() => {
782                 return Ok(None)
783             }
784             Some(aki) => aki,
785             None => return Ok(None)
786         };
787 
788         let mut found = false;
789         for ca in cas {
790             if ca.cert.subject_key_identifier() != aki {
791                 continue
792             }
793             found = true;
794             if self.cert.verify_signature(ca.cert, strict).is_err() {
795                 continue
796             }
797             return Ok(Some(ca))
798         }
799         if found {
800             xerr!(Err(ValidationError))
801         }
802         else {
803             Ok(None)
804         }
805     }
806 
apply_ca(&mut self, ca: &Ca<'a>) -> Result<(), ValidationError>807     fn apply_ca(&mut self, ca: &Ca<'a>) -> Result<(), ValidationError> {
808         // Check that our cert hasn’t been revoked.
809         if ca.crl.contains(self.cert.serial_number()) {
810             xerr!(return Err(ValidationError))
811         }
812 
813         // Check if the CA allows us to have our resources.
814         self.verify_resources(ca)?;
815 
816         // Now update self to reflect the new head of chain cert.
817         self.update_head(ca);
818 
819         Ok(())
820     }
821 
verify_resources(&self, ca: &Ca) -> Result<(), ValidationError>822     fn verify_resources(&self, ca: &Ca) -> Result<(), ValidationError> {
823         // If our cert is of the resource trimming kind, we don’t actually
824         // need to check but rather have to trim resources later on.
825         if self.cert.overclaim() == Overclaim::Trim {
826             return Ok(())
827         }
828 
829         // If we have a certain resource, it needs to be covered by the CA.
830         // If the CA has that resource as inherited, that qualifies as valid,
831         // too.
832         if let Some(blocks) = self.cert_resources.as_resources.as_ref() {
833             blocks.verify_covered(ca.cert.as_resources())?
834         }
835         if let Some(blocks) = self.cert_resources.v4_resources.as_ref() {
836             blocks.verify_covered(ca.cert.v4_resources())?
837         }
838         if let Some(blocks) = self.cert_resources.v6_resources.as_ref() {
839             blocks.verify_covered(ca.cert.v6_resources())?
840         }
841 
842         Ok(())
843     }
844 
update_head(&mut self, ca: &Ca<'a>)845     fn update_head(&mut self, ca: &Ca<'a>) {
846         // Let’s get the CA’s resources so we can play with them.
847         let ca_resources = CertResources::new(ca.cert);
848 
849         // If our current head has a resource trimming certificate, we first
850         // need to trim back the chain resources to whatever the CA allows.
851         if self.cert.overclaim() == Overclaim::Trim {
852             self.chain_resources.trim_to(&ca_resources);
853         }
854 
855         // Next we update remaining inherited chain resources to what the CA
856         // has (unless it is inherited, too).
857         self.chain_resources.replace_inherited(&ca_resources);
858 
859         // Now we can update the head resources and certificate, leaving
860         // inherited resources in the CA untouched.
861         self.cert_resources.update_head(ca_resources);
862         self.cert = ca.cert;
863     }
864 
865 
866     //--- supply_tal and supply_ca
867 
supply_tal( &mut self, tal: &Tal, strict: bool, now: Time ) -> Result<bool, ValidationError>868     fn supply_tal(
869         &mut self, tal: &Tal, strict: bool, now: Time
870     ) -> Result<bool, ValidationError> {
871         if self.validated {
872             return Ok(true)
873         }
874 
875         // If we have a self-signed certificate, it is a TA certificate and
876         // we don’t need to bother checking.
877         if self.cert.is_self_signed() {
878             return Ok(false)
879         }
880 
881         // Let’s see if the key matches.
882         if self.cert.subject_public_key_info() != tal.key_info() {
883             return Ok(false)
884         }
885 
886         // Finally, let’s see if we have a proper TA certificate. We only do
887         // this now so we don’t check over and over again. We also will never
888         // check a certificate that doesn’t have a matching TAL which will
889         // safe a little extra time.
890         self.cert.inspect_ta_at(strict, now)?;
891         self.cert.verify_ta_ref(strict)?;
892 
893         self.validated = true;
894         Ok(true)
895     }
896 
supply_ca( &mut self, ca: &ResourceCert, strict: bool, now: Time ) -> Result<bool, ValidationError>897     fn supply_ca(
898         &mut self, ca: &ResourceCert, strict: bool, now: Time
899     ) -> Result<bool, ValidationError> {
900         if self.validated {
901             return Ok(true)
902         }
903 
904         // Quick check first: If we don’t have an AKI, we are our own CA and
905         // don’t need to continue here.
906         if self.cert.authority_key_identifier().is_none() {
907             return Ok(false)
908         }
909 
910         // Now check properly if `ca` should be our CA and return if it isn’t.
911         //
912         // If it isn’t not all is lost. There may just be a key identifier
913         // collision or something. Unlikely but hey.
914         if self.cert.verify_issuer_claim(ca, strict).is_err()
915             || self.cert.verify_signature(ca, strict).is_err()
916         {
917             return Ok(false)
918         }
919 
920         // Now let’s see if our certificate is a proper CA or EE certificate.
921         //
922         // basic_ca must be present (and true) for CA certs and not present
923         // for EE certs, so we can use that. If it has the wrong value, the
924         // cert is broken, so the check will fail and all is good.
925         //
926         // We will error out here if the cert is broken because, well, the
927         // cert is broken.
928         if self.cert.basic_ca().is_some() {
929             self.cert.inspect_ca_at(strict, now)?;
930         }
931         else {
932             self.cert.inspect_detached_ee_at(strict, now)?;
933         }
934 
935         // Finally, resources. If they don’t check out, we can error out ...
936         // I think.
937         //
938         // Remember that our cert may be of the resource trimming kind,
939         // though.
940         if self.cert.overclaim() == Overclaim::Trim {
941             self.chain_resources.trim_to_issuer(ca);
942         }
943         else {
944             self.cert_resources.verify_issuer(ca)?;
945         }
946 
947         // If we still have inherited resources left, replace them with the
948         // CA cert.
949         self.chain_resources.replace_inherited_from_issuer(ca);
950 
951         self.validated = true;
952         Ok(true)
953     }
954 
955     //--- finalize
956 
finalize( &self, asn: &mut AsBlocksBuilder, v4: &mut IpBlocksBuilder, v6: &mut IpBlocksBuilder ) -> Result<(), ValidationError>957     fn finalize(
958         &self,
959         asn: &mut AsBlocksBuilder,
960         v4: &mut IpBlocksBuilder,
961         v6: &mut IpBlocksBuilder
962     ) -> Result<(), ValidationError> {
963         if !self.validated {
964             return Err(ValidationError)
965         }
966 
967         // Add all our resources to the collection of resources.
968         //
969         // We can’t really have inherited resources left (if the top was a TA
970         // certificate, we should have rejected it already in this case and
971         // otherwise we checked it against a resource CA cert from outside
972         // which always has all resources) resources left, so let’s unwrap
973         // here to indicate a programming error.
974         asn.extend(self.chain_resources.as_resources.as_ref().unwrap().iter());
975         v4.extend(self.chain_resources.v4_resources.as_ref().unwrap().iter());
976         v6.extend(self.chain_resources.v6_resources.as_ref().unwrap().iter());
977 
978         Ok(())
979     }
980 }
981 
982 
983 //------------ CertResources -------------------------------------------------
984 
985 #[derive(Clone, Debug)]
986 struct CertResources {
987     /// The AS resources.
988     ///
989     /// A value of `None` means the resources are inherited from the CA.
990     as_resources: Option<AsBlocks>,
991 
992     /// The IPv4 resources.
993     ///
994     /// A value of `None` means the resources are inherited from the CA.
995     v4_resources: Option<IpBlocks>,
996 
997     /// The IPv6 resources.
998     ///
999     /// A value of `None` means the resources are inherited from the CA.
1000     v6_resources: Option<IpBlocks>,
1001 }
1002 
1003 impl CertResources {
new(cert: &Cert) -> Self1004     fn new(cert: &Cert) -> Self {
1005         CertResources {
1006             as_resources: cert.as_resources().to_blocks().ok(),
1007             v4_resources: cert.v4_resources().to_blocks().ok(),
1008             v6_resources: cert.v6_resources().to_blocks().ok(),
1009         }
1010     }
1011 
trim_to(&mut self, ca: &CertResources)1012     fn trim_to(&mut self, ca: &CertResources) {
1013         if let (Some(my), Some(them)) = (
1014             self.as_resources.as_mut(), ca.as_resources.as_ref()
1015         ) {
1016             my.intersection_assign(them)
1017         }
1018         if let (Some(my), Some(them)) = (
1019             self.v4_resources.as_mut(), ca.v4_resources.as_ref()
1020         ) {
1021             my.intersection_assign(them)
1022         }
1023         if let (Some(my), Some(them)) = (
1024             self.v6_resources.as_mut(), ca.v6_resources.as_ref()
1025         ) {
1026             my.intersection_assign(them)
1027         }
1028     }
1029 
trim_to_issuer(&mut self, issuer: &ResourceCert)1030     fn trim_to_issuer(&mut self, issuer: &ResourceCert) {
1031         if let Some(res) = self.as_resources.as_mut() {
1032             res.intersection_assign(issuer.as_resources())
1033         }
1034         if let Some(res) = self.v4_resources.as_mut() {
1035             res.intersection_assign(issuer.v4_resources())
1036         }
1037         if let Some(res) = self.v6_resources.as_mut() {
1038             res.intersection_assign(issuer.v6_resources())
1039         }
1040     }
1041 
verify_issuer( &self, issuer: &ResourceCert ) -> Result<(), ValidationError>1042     fn verify_issuer(
1043         &self, issuer: &ResourceCert
1044     ) -> Result<(), ValidationError> {
1045         if let Some(res) = self.as_resources.as_ref() {
1046             if !issuer.as_resources().contains(res) {
1047                 return Err(ValidationError)
1048             }
1049         }
1050         if let Some(res) = self.v4_resources.as_ref() {
1051             if !issuer.v4_resources().contains(res) {
1052                 return Err(ValidationError)
1053             }
1054         }
1055         if let Some(res) = self.v6_resources.as_ref() {
1056             if !issuer.v6_resources().contains(res) {
1057                 return Err(ValidationError)
1058             }
1059         }
1060         Ok(())
1061     }
1062 
replace_inherited(&mut self, ca: &CertResources)1063     fn replace_inherited(&mut self, ca: &CertResources) {
1064         if self.as_resources.is_none() {
1065             self.as_resources = ca.as_resources.clone()
1066         }
1067         if self.v4_resources.is_none() {
1068             self.v4_resources = ca.v4_resources.clone()
1069         }
1070         if self.v6_resources.is_none() {
1071             self.v6_resources = ca.v6_resources.clone()
1072         }
1073     }
1074 
replace_inherited_from_issuer(&mut self, ca: &ResourceCert)1075     fn replace_inherited_from_issuer(&mut self, ca: &ResourceCert) {
1076         if self.as_resources.is_none() {
1077             self.as_resources = Some(ca.as_resources().clone())
1078         }
1079         if self.v4_resources.is_none() {
1080             self.v4_resources = Some(ca.v4_resources().clone())
1081         }
1082         if self.v6_resources.is_none() {
1083             self.v6_resources = Some(ca.v6_resources().clone())
1084         }
1085     }
1086 
update_head(&mut self, ca: CertResources)1087     fn update_head(&mut self, ca: CertResources) {
1088         if let Some(res) = ca.as_resources {
1089             self.as_resources = Some(res)
1090         }
1091         if let Some(res) = ca.v4_resources {
1092             self.v4_resources = Some(res)
1093         }
1094         if let Some(res) = ca.v6_resources {
1095             self.v6_resources = Some(res)
1096         }
1097     }
1098 }
1099 
1100 
1101 //------------ AttestationBuilder --------------------------------------------
1102 
1103 pub struct AttestationBuilder {
1104     keys: Vec<KeyIdentifier>,
1105     as_resources: AsBlocksBuilder,
1106     v4_resources: IpBlocksBuilder,
1107     v6_resources: IpBlocksBuilder,
1108     digest_algorithm: DigestAlgorithm,
1109     message_digest: MessageDigest,
1110 }
1111 
1112 impl AttestationBuilder {
new( digest_algorithm: DigestAlgorithm, message_digest: MessageDigest ) -> Self1113     pub fn new(
1114         digest_algorithm: DigestAlgorithm,
1115         message_digest: MessageDigest
1116     ) -> Self {
1117         AttestationBuilder {
1118             keys: Vec::new(),
1119             as_resources: AsBlocksBuilder::new(),
1120             v4_resources: IpBlocksBuilder::new(),
1121             v6_resources: IpBlocksBuilder::new(),
1122             digest_algorithm, message_digest
1123         }
1124     }
1125 
push_key(&mut self, key: KeyIdentifier)1126     pub fn push_key(&mut self, key: KeyIdentifier) {
1127         self.keys.push(key)
1128     }
1129 
keys(&self) -> &[KeyIdentifier]1130     pub fn keys(&self) -> &[KeyIdentifier] {
1131         &self.keys
1132     }
1133 
keys_mut(&mut self) -> &mut Vec<KeyIdentifier>1134     pub fn keys_mut(&mut self) -> &mut Vec<KeyIdentifier> {
1135         &mut self.keys
1136     }
1137 
push_as(&mut self, block: impl Into<AsBlock>)1138     pub fn push_as(&mut self, block: impl Into<AsBlock>) {
1139         self.as_resources.push(block)
1140     }
1141 
as_resources(&self) -> &AsBlocksBuilder1142     pub fn as_resources(&self) -> &AsBlocksBuilder {
1143         &self.as_resources
1144     }
1145 
as_resources_mut(&mut self) -> &mut AsBlocksBuilder1146     pub fn as_resources_mut(&mut self) -> &mut AsBlocksBuilder {
1147         &mut self.as_resources
1148     }
1149 
push_v4(&mut self, block: impl Into<IpBlock>)1150     pub fn push_v4(&mut self, block: impl Into<IpBlock>) {
1151         self.v4_resources.push(block)
1152     }
1153 
v4_resources(&self) -> &IpBlocksBuilder1154     pub fn v4_resources(&self) -> &IpBlocksBuilder {
1155         &self.v4_resources
1156     }
1157 
v4_resources_mut(&mut self) ->&mut IpBlocksBuilder1158     pub fn v4_resources_mut(&mut self) ->&mut IpBlocksBuilder {
1159         &mut self.v4_resources
1160     }
1161 
push_v6(&mut self, block: impl Into<IpBlock>)1162     pub fn push_v6(&mut self, block: impl Into<IpBlock>) {
1163         self.v6_resources.push(block)
1164     }
1165 
v6_resources(&self) -> &IpBlocksBuilder1166     pub fn v6_resources(&self) -> &IpBlocksBuilder {
1167         &self.v6_resources
1168     }
1169 
v6_resources_mut(&mut self) -> &mut IpBlocksBuilder1170     pub fn v6_resources_mut(&mut self) -> &mut IpBlocksBuilder {
1171         &mut self.v6_resources
1172     }
1173 
into_attestation(self) -> ResourceTaggedAttestation1174     pub fn into_attestation(self) -> ResourceTaggedAttestation {
1175         ResourceTaggedAttestation {
1176             subject_keys: self.keys,
1177             as_resources: self.as_resources.finalize(),
1178             v4_resources: self.v4_resources.finalize(),
1179             v6_resources: self.v6_resources.finalize(),
1180             digest_algorithm: self.digest_algorithm,
1181             message_digest: self.message_digest,
1182         }
1183     }
1184 
into_rta_builder(self) -> RtaBuilder1185     pub fn into_rta_builder(self) -> RtaBuilder {
1186         RtaBuilder::from_attestation(self.into_attestation())
1187     }
1188 }
1189 
1190 
1191 //------------ RtaBuilder ----------------------------------------------------
1192 
1193 pub struct RtaBuilder {
1194     digest_algorithm: DigestAlgorithm,
1195     encoded_content: Bytes,
1196     content: ResourceTaggedAttestation,
1197     certificates: Vec<Cert>,
1198     crls: Vec<Crl>,
1199     signer_infos: Vec<SignerInfo>,
1200 }
1201 
1202 impl RtaBuilder {
from_attestation(content: ResourceTaggedAttestation) -> Self1203     pub fn from_attestation(content: ResourceTaggedAttestation) -> Self {
1204         RtaBuilder {
1205             digest_algorithm: DigestAlgorithm::default(),
1206             encoded_content: content.to_bytes(),
1207             content,
1208             certificates: Vec::new(),
1209             crls: Vec::new(),
1210             signer_infos: Vec::new()
1211         }
1212     }
1213 
from_rta(rta: Rta) -> Self1214     pub fn from_rta(rta: Rta) -> Self {
1215         RtaBuilder {
1216             digest_algorithm: DigestAlgorithm::default(),
1217             encoded_content: rta.signed.content.to_bytes(),
1218             content: rta.content,
1219             certificates: rta.signed.certificates,
1220             crls: rta.signed.crls,
1221             signer_infos: rta.signed.signer_infos,
1222         }
1223     }
1224 
content(&self) -> &ResourceTaggedAttestation1225     pub fn content(&self) -> &ResourceTaggedAttestation {
1226         &self.content
1227     }
1228 
push_cert(&mut self, cert: Cert)1229     pub fn push_cert(&mut self, cert: Cert) {
1230         self.certificates.push(cert)
1231     }
1232 
certificates(&self) -> &[Cert]1233     pub fn certificates(&self) -> &[Cert] {
1234         &self.certificates
1235     }
1236 
certificates_mut(&mut self) -> &mut Vec<Cert>1237     pub fn certificates_mut(&mut self) -> &mut Vec<Cert> {
1238         &mut self.certificates
1239     }
1240 
push_crl(&mut self, crl: Crl)1241     pub fn push_crl(&mut self, crl: Crl) {
1242         self.crls.push(crl)
1243     }
1244 
crls(&self) -> &[Crl]1245     pub fn crls(&self) -> &[Crl] {
1246         &self.crls
1247     }
1248 
crls_mut(&mut self) -> &mut Vec<Crl>1249     pub fn crls_mut(&mut self) -> &mut Vec<Crl> {
1250         &mut self.crls
1251     }
1252 
sign<S: Signer>( &mut self, signer: &S, key: &S::KeyId, signing_time: Option<Time>, binary_signing_time: Option<u64>, ) -> Result<(), SigningError<S::Error>>1253     pub fn sign<S: Signer>(
1254         &mut self,
1255         signer: &S,
1256         key: &S::KeyId,
1257         signing_time: Option<Time>,
1258         binary_signing_time: Option<u64>,
1259     ) -> Result<(), SigningError<S::Error>> {
1260         // Produce the content digest
1261         let message_digest = self.digest_algorithm.digest(
1262             &self.encoded_content
1263         ).into();
1264 
1265         // Produce signed attributes.
1266         let signed_attrs = SignedAttrs::new(
1267             &oid::CT_RESOURCE_TAGGED_ATTESTATION,
1268             &message_digest,
1269             signing_time,
1270             binary_signing_time
1271         );
1272 
1273         // Sign those attributes
1274         let signature = signer.sign(
1275             key, SignatureAlgorithm::default(),
1276             &signed_attrs.encode_verify()
1277         )?;
1278 
1279         self.signer_infos.push(SignerInfo {
1280             sid: KeyIdentifier::from_public_key(&signer.get_key_info(key)?),
1281             digest_algorithm: self.digest_algorithm,
1282             signed_attrs,
1283             signature,
1284             message_digest,
1285             signing_time,
1286             binary_signing_time
1287         });
1288         Ok(())
1289     }
1290 
signer_infos(&self) -> &[SignerInfo]1291     pub fn signer_infos(&self) -> &[SignerInfo] {
1292         &self.signer_infos
1293     }
1294 
signer_infos_mut(&mut self) -> &mut Vec<SignerInfo>1295     pub fn signer_infos_mut(&mut self) -> &mut Vec<SignerInfo> {
1296         &mut self.signer_infos
1297     }
1298 
finalize(self) -> Rta1299     pub fn finalize(self) -> Rta {
1300         Rta {
1301             signed: MultiSignedObject {
1302                 digest_algorithm: self.digest_algorithm,
1303                 content: OctetString::new(self.encoded_content),
1304                 certificates: self.certificates,
1305                 crls: self.crls,
1306                 signer_infos: self.signer_infos,
1307             },
1308             content: self.content,
1309         }
1310     }
1311 }
1312 
1313