1 //! Signed objects.
2 //
3 // See RFC 6488 and RFC 5652.
4 
5 use std::{cmp, io};
6 use bcder::{decode, encode};
7 use bcder::{Captured, Mode, OctetString, Oid, Tag, xerr};
8 use bcder::encode::PrimitiveContent;
9 use bcder::string::OctetStringSource;
10 use bytes::Bytes;
11 use crate::uri;
12 use super::oid;
13 use super::cert::{Cert, KeyUsage, Overclaim, ResourceCert, TbsCert};
14 use super::crypto::{
15     Digest, DigestAlgorithm, KeyIdentifier, Signature, SignatureAlgorithm,
16     Signer, SigningError
17 };
18 use super::resources::{
19     AsBlocksBuilder, AsResources, AsResourcesBuilder, IpBlocksBuilder,
20     IpResources, IpResourcesBuilder
21 };
22 use super::x509::{Name, Serial, Time, ValidationError, Validity, update_once};
23 
24 
25 //------------ SignedObject --------------------------------------------------
26 
27 /// A signed object.
28 #[derive(Clone, Debug)]
29 pub struct SignedObject {
30     //--- From SignedData
31     //
32     digest_algorithm: DigestAlgorithm,
33     content_type: Oid<Bytes>,
34     content: OctetString,
35     cert: Cert,
36 
37     //--- From SignerInfo
38     //
39     sid: KeyIdentifier,
40     signed_attrs: SignedAttrs,
41     signature: Signature,
42 
43     //--- SignedAttributes
44     //
45     message_digest: MessageDigest,
46     signing_time: Option<Time>,
47     binary_signing_time: Option<u64>,
48 }
49 
50 /// # Data Access
51 ///
52 impl SignedObject {
53     /// Returns a reference to the object’s content type.
content_type(&self) -> &Oid<Bytes>54     pub fn content_type(&self) -> &Oid<Bytes> {
55         &self.content_type
56     }
57 
58     /// Returns a reference to the object’s content.
content(&self) -> &OctetString59     pub fn content(&self) -> &OctetString {
60         &self.content
61     }
62 
63     /// 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>64     pub fn decode_content<F, T>(&self, op: F) -> Result<T, decode::Error>
65     where F: FnOnce(&mut decode::Constructed<OctetStringSource>)
66                     -> Result<T, decode::Error> {
67         // XXX Let’s see if using DER here at least holds.
68         Mode::Der.decode(self.content.to_source(), op)
69     }
70 
71     /// Returns a reference to the certificate the object is signed with.
cert(&self) -> &Cert72     pub fn cert(&self) -> &Cert {
73         &self.cert
74     }
75 }
76 
77 /// # Decoding, Validation, and Encoding
78 ///
79 impl SignedObject {
80     /// Decodes a signed object from the given source.
decode<S: decode::Source>( source: S, strict: bool ) -> Result<Self, S::Err>81     pub fn decode<S: decode::Source>(
82         source: S,
83         strict: bool
84     ) -> Result<Self, S::Err> {
85         if strict { Mode::Der }
86         else { Mode::Ber }
87             .decode(source, Self::take_from)
88     }
89 
90     /// Takes a signed object from an encoded constructed value.
take_from<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result<Self, S::Err>91     pub fn take_from<S: decode::Source>(
92         cons: &mut decode::Constructed<S>
93     ) -> Result<Self, S::Err> {
94         cons.take_sequence(|cons| { // ContentInfo
95             oid::SIGNED_DATA.skip_if(cons)?; // contentType
96             cons.take_constructed_if(Tag::CTX_0, |cons| { // content
97                 cons.take_sequence(|cons| { // SignedData
98                     cons.skip_u8_if(3)?; // version -- must be 3
99                     let digest_algorithm =
100                         DigestAlgorithm::take_set_from(cons)?;
101                     let (content_type, content) = {
102                         cons.take_sequence(|cons| { // encapContentInfo
103                             Ok((
104                                 Oid::take_from(cons)?,
105                                 cons.take_constructed_if(
106                                     Tag::CTX_0,
107                                     OctetString::take_from
108                                 )?
109                             ))
110                         })?
111                     };
112                     let cert = cons.take_constructed_if( // certificates
113                         Tag::CTX_0,
114                         Cert::take_from
115                     )?;
116                     // no crls
117                     let (sid, attrs, signature) = { // signerInfos
118                         cons.take_set(|cons| {
119                             cons.take_sequence(|cons| {
120                                 cons.skip_u8_if(3)?;
121                                 let sid = cons.take_value_if(
122                                     Tag::CTX_0, |content| {
123                                         KeyIdentifier::from_content(content)
124                                     }
125                                 )?;
126                                 let alg = DigestAlgorithm::take_from(cons)?;
127                                 if alg != digest_algorithm {
128                                     return Err(decode::Malformed.into())
129                                 }
130                                 let attrs = SignedAttrs::take_from(cons)?;
131                                 if attrs.2 != content_type {
132                                     return Err(decode::Malformed.into())
133                                 }
134                                 let signature = Signature::new(
135                                     SignatureAlgorithm::cms_take_from(cons)?,
136                                     OctetString::take_from(cons)?.into_bytes()
137                                 );
138                                 // no unsignedAttributes
139                                 Ok((sid, attrs, signature))
140                             })
141                         })?
142                     };
143                     Ok(Self {
144                         digest_algorithm,
145                         content_type,
146                         content,
147                         cert,
148                         sid,
149                         signed_attrs: attrs.0,
150                         signature,
151                         message_digest: attrs.1,
152                         signing_time: attrs.3,
153                         binary_signing_time: attrs.4
154                     })
155                 })
156             })
157         })
158     }
159 
process<F>( self, issuer: &ResourceCert, strict: bool, check_crl: F ) -> Result<(ResourceCert, Bytes), ValidationError> where F: FnOnce(&Cert) -> Result<(), ValidationError>160     pub fn process<F>(
161         self,
162         issuer: &ResourceCert,
163         strict: bool,
164         check_crl: F
165     ) -> Result<(ResourceCert, Bytes), ValidationError>
166     where F: FnOnce(&Cert) -> Result<(), ValidationError> {
167         let res = self.content.clone();
168         let cert = self.validate(issuer, strict)?;
169         check_crl(cert.as_ref())?;
170         Ok((cert, res.into_bytes()))
171     }
172 
173     /// Validates the signed object.
174     ///
175     /// Upon success, the method returns the validated EE certificate of the
176     /// object.
validate( self, issuer: &ResourceCert, strict: bool, ) -> Result<ResourceCert, ValidationError>177     pub fn validate(
178         self,
179         issuer: &ResourceCert,
180         strict: bool,
181     ) -> Result<ResourceCert, ValidationError> {
182         self.validate_at(issuer, strict, Time::now())
183     }
184 
185     /// Validates the signed object at he given time.
validate_at( self, issuer: &ResourceCert, strict: bool, now: Time, ) -> Result<ResourceCert, ValidationError>186     pub fn validate_at(
187         self,
188         issuer: &ResourceCert,
189         strict: bool,
190         now: Time,
191     ) -> Result<ResourceCert, ValidationError> {
192         self.verify_compliance(strict)?;
193         self.verify_signature(strict)?;
194         self.cert.validate_ee_at(issuer, strict, now)
195     }
196 
197     /// Validates that the signed object complies with the specification.
198     ///
199     /// This is item 1 of [RFC 6488]`s section 3.
verify_compliance( &self, _strict: bool ) -> Result<(), ValidationError>200     fn verify_compliance(
201         &self,
202         _strict: bool
203     ) -> Result<(), ValidationError> {
204         // Sub-items a, b, d, e, f, g, h, i, j, k, l have been validated while
205         // parsing. This leaves these:
206         //
207         // c. cert is an EE cert with the SubjectKeyIdentifer matching
208         //    the sid field of the SignerInfo.
209         if self.sid != self.cert.subject_key_identifier() {
210             return Err(ValidationError)
211         }
212         Ok(())
213     }
214 
215     /// Verifies the signature of the object against contained certificate.
216     ///
217     /// This is item 2 of [RFC 6488]’s section 3.
verify_signature(&self, _strict: bool) -> Result<(), ValidationError>218     fn verify_signature(&self, _strict: bool) -> Result<(), ValidationError> {
219         let digest = {
220             let mut context = self.digest_algorithm.start();
221             self.content.iter().for_each(|x| context.update(x));
222             context.finish()
223         };
224         if digest.as_ref() != self.message_digest.as_ref() {
225             return Err(ValidationError)
226         }
227         let msg = self.signed_attrs.encode_verify();
228         self.cert.subject_public_key_info().verify(
229             &msg,
230             &self.signature
231         ).map_err(Into::into)
232     }
233 
234     /// Returns a value encoder for a reference to a signed object.
encode_ref(&self) -> impl encode::Values + '_235     pub fn encode_ref(&self) -> impl encode::Values + '_ {
236         encode::sequence((
237             oid::SIGNED_DATA.encode(), // contentType
238             encode::sequence_as(Tag::CTX_0, // content
239                 encode::sequence((
240                     3u8.encode(), // version
241                     self.digest_algorithm.encode_set(), // digestAlgorithms
242                     encode::sequence(( // encapContentInfo
243                         self.content_type.encode_ref(),
244                         encode::sequence_as(Tag::CTX_0,
245                             self.content.encode_ref()
246                         ),
247                     )),
248                     encode::sequence_as(Tag::CTX_0, // certificates
249                         self.cert.encode_ref(),
250                     ),
251                     // crl -- omitted
252                     encode::set( // signerInfo
253                         encode::sequence(( // SignerInfo
254                             3u8.encode(), // version
255                             self.sid.encode_ref_as(Tag::CTX_0),
256                             self.digest_algorithm.encode(), // digestAlgorithm
257                             self.signed_attrs.encode_ref(), // signedAttrs
258                             self.signature.algorithm().cms_encode(),
259                                                         // signatureAlgorithm
260                             OctetString::encode_slice( // signature
261                                 self.signature.value().as_ref()
262                             ),
263                             // unsignedAttrs omitted
264                         ))
265                     )
266                 ))
267             )
268         ))
269     }
270 }
271 
272 
273 //------------ SignedAttrs ---------------------------------------------------
274 
275 /// A private helper type that contains the raw signed attributes content.
276 ///
277 /// These attributes, in their DER encoded form, are what the signature is
278 /// calculated over. Annoyingly, the encoding uses the signed attribute set
279 /// with a tag for SET OF, not \[0\] as it would be found in the actual data.
280 ///
281 /// Technically, signed objects need to be DER encoded, anyway, so we would
282 /// not need to re-encode the signed attributes other than sticking the SET OF
283 /// tag and length in front of them. While we do allow BER encoded objects in
284 /// relaxed mode, those that we have encountered have their signed attributes
285 /// in DER encoding still, so we don’t re-encode.
286 ///
287 /// A `SignedAttrs` value contains the captured content of the signed
288 /// attributes set. That is, it does not contain the tag and length values of
289 /// the outer set object, only two to four sequences of the actual
290 /// attributes.
291 ///
292 /// In order to make sticking tag and length in front of the value easier, we
293 /// allow a maximum length of the s content of 65536 octets.
294 #[derive(Clone, Debug)]
295 pub struct SignedAttrs(Captured);
296 
297 impl SignedAttrs {
new( content_type: &Oid<impl AsRef<[u8]>>, digest: &MessageDigest, signing_time: Option<Time>, binary_signing_time: Option<u64>, ) -> Self298     pub(crate) fn new(
299         content_type: &Oid<impl AsRef<[u8]>>,
300         digest: &MessageDigest,
301         signing_time: Option<Time>,
302         binary_signing_time: Option<u64>,
303     ) -> Self {
304         // In DER encoding, the values of SET OFs is ordered via the octet
305         // string of their DER encoding. Given that all our values are
306         // SEQUENCEs, their first octet will always be 30. So we only have to
307         // compare the length octets. Unfortunately, two of the values are
308         // variable length, so we need to get creative.
309 
310         let mut content_type = Some(encode::sequence((
311             oid::CONTENT_TYPE.encode(),
312             encode::set(
313                 content_type.encode_ref(),
314             )
315         )));
316         let mut signing_time = signing_time.map(|time| {
317             encode::sequence((
318                 oid::SIGNING_TIME.encode(),
319                 encode::set(
320                     time.encode_varied(),
321                     )
322             ))
323         });
324         let mut message_digest = Some(encode::sequence((
325             oid::MESSAGE_DIGEST.encode(),
326             encode::set(
327                 digest.encode_ref(),
328             )
329         )));
330         let mut binary_signing_time = binary_signing_time.map(|time| {
331             encode::sequence((
332                 oid::AA_BINARY_SIGNING_TIME.encode(),
333                 encode::set(
334                     time.encode()
335                 )
336             ))
337         });
338 
339         let mut len = [
340             (0, StartOfValue::new(&content_type)),
341             (1, StartOfValue::new(&signing_time)),
342             (2, StartOfValue::new(&message_digest)),
343             (3, StartOfValue::new(&binary_signing_time)),
344         ];
345         len.sort_by_key(|&(_, len)| len.unwrap());
346 
347         let mut res = Captured::builder(Mode::Der);
348         for &(idx, _) in &len {
349             match idx {
350                 0 => {
351                     if let Some(val) = content_type.take() {
352                         res.extend(val)
353                     }
354                 }
355                 1 => {
356                     if let Some(val) = signing_time.take() {
357                         res.extend(val)
358                     }
359                 }
360                 2 => {
361                     if let Some(val) = message_digest.take() {
362                         res.extend(val)
363                     }
364                 }
365                 3 => {
366                     if let Some(val) = binary_signing_time.take() {
367                         res.extend(val)
368                     }
369                 }
370                 _ => unreachable!()
371             }
372         }
373 
374        SignedAttrs(res.freeze())
375     }
376 
377     /// Takes the signed attributes from the beginning of a constructed value.
378     ///
379     /// Returns the raw signed attrs, the message digest, the content type
380     /// object identifier, and the two optional signing times.
381     ///
382     /// If strict is true, any unknown signed attributes are rejected, if
383     /// strict is false they will be ignored.
384     #[allow(clippy::type_complexity)]
take_from_with_mode<S: decode::Source>( cons: &mut decode::Constructed<S>, strict: bool ) -> Result< (Self, MessageDigest, Oid<Bytes>, Option<Time>, Option<u64>), S::Err >385     fn take_from_with_mode<S: decode::Source>(
386         cons: &mut decode::Constructed<S>,
387         strict: bool
388     ) -> Result<
389         (Self, MessageDigest, Oid<Bytes>, Option<Time>, Option<u64>),
390         S::Err
391     > {
392         let mut message_digest = None;
393         let mut content_type = None;
394         let mut signing_time = None;
395         let mut binary_signing_time = None;
396         let raw = cons.take_constructed_if(Tag::CTX_0, |cons| {
397             cons.capture(|cons| {
398                 while let Some(()) = cons.take_opt_sequence(|cons| {
399                     let oid = Oid::take_from(cons)?;
400                     if oid == oid::CONTENT_TYPE {
401                         Self::take_content_type(cons, &mut content_type)
402                     }
403                     else if oid == oid::MESSAGE_DIGEST {
404                         Self::take_message_digest(cons, &mut message_digest)
405                     }
406                     else if oid == oid::SIGNING_TIME {
407                         Self::take_signing_time(cons, &mut signing_time)
408                     }
409                     else if oid == oid::AA_BINARY_SIGNING_TIME {
410                         Self::take_bin_signing_time(
411                             cons,
412                             &mut binary_signing_time
413                         )
414                     }
415                     else if !strict {
416                         cons.skip_all()
417                     } else {
418                         xerr!(Err(decode::Malformed.into()))
419                     }
420                 })? { }
421                 Ok(())
422             })
423         })?;
424         if raw.len() > 0xFFFF {
425             return Err(decode::Unimplemented.into())
426         }
427         let message_digest = match message_digest {
428             Some(some) => MessageDigest(some.into_bytes()),
429             None => return Err(decode::Malformed.into())
430         };
431         let content_type = match content_type {
432             Some(some) => some,
433             None => return Err(decode::Malformed.into())
434         };
435         Ok((
436             Self(raw), message_digest, content_type, signing_time,
437             binary_signing_time
438         ))
439     }
440 
441 
442 
443     /// Takes the signed attributes from the beginning of a constructed value.
444     ///
445     /// Returns the raw signed attrs, the message digest, the content type
446     /// object identifier, and the two optional signing times.
447     #[allow(clippy::type_complexity)]
take_from<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result< (Self, MessageDigest, Oid<Bytes>, Option<Time>, Option<u64>), S::Err >448     pub fn take_from<S: decode::Source>(
449         cons: &mut decode::Constructed<S>
450     ) -> Result<
451         (Self, MessageDigest, Oid<Bytes>, Option<Time>, Option<u64>),
452         S::Err
453     > {
454         Self::take_from_with_mode(cons, true)
455     }
456 
457     /// Takes the signed attributes from the beginning of a constructed value.
458     ///
459     /// Note this function should be used for parsing CMS used in RFC6492 and
460     /// RFC8181 messages only, as it will ignore any unknown signed attributes.
461     /// Unfortunately the profile for the Certificates and CMS used is not
462     /// well-defined in these RFCs. So, in this case, we should be more
463     /// accepting.
464     ///
465     /// Returns the raw signed attrs, the message digest, the content type
466     /// object identifier, and the two optional signing times.
467     #[allow(clippy::type_complexity)]
take_from_signed_message<S: decode::Source>( cons: &mut decode::Constructed<S> ) -> Result< (Self, MessageDigest, Oid<Bytes>, Option<Time>, Option<u64>), S::Err >468     pub fn take_from_signed_message<S: decode::Source>(
469         cons: &mut decode::Constructed<S>
470     ) -> Result<
471         (Self, MessageDigest, Oid<Bytes>, Option<Time>, Option<u64>),
472         S::Err
473     > {
474         Self::take_from_with_mode(cons, false)
475     }
476 
477     /// Parses the Content Type attribute.
478     ///
479     /// This attribute is defined in section 11.1. of RFC 5652. The attribute
480     /// value is a SET of exactly one OBJECT IDENTIFIER.
take_content_type<S: decode::Source>( cons: &mut decode::Constructed<S>, content_type: &mut Option<Oid<Bytes>> ) -> Result<(), S::Err>481     fn take_content_type<S: decode::Source>(
482         cons: &mut decode::Constructed<S>,
483         content_type: &mut Option<Oid<Bytes>>
484     ) -> Result<(), S::Err> {
485         update_once(content_type, || {
486             cons.take_set(|cons| Oid::take_from(cons))
487         })
488     }
489 
take_message_digest<S: decode::Source>( cons: &mut decode::Constructed<S>, message_digest: &mut Option<OctetString> ) -> Result<(), S::Err>490     fn take_message_digest<S: decode::Source>(
491         cons: &mut decode::Constructed<S>,
492         message_digest: &mut Option<OctetString>
493     ) -> Result<(), S::Err> {
494         update_once(message_digest, || {
495             cons.take_set(|cons| OctetString::take_from(cons))
496         })
497     }
498 
take_signing_time<S: decode::Source>( cons: &mut decode::Constructed<S>, signing_time: &mut Option<Time> ) -> Result<(), S::Err>499     fn take_signing_time<S: decode::Source>(
500         cons: &mut decode::Constructed<S>,
501         signing_time: &mut Option<Time>
502     ) -> Result<(), S::Err> {
503         update_once(signing_time, || {
504             cons.take_set(Time::take_from)
505         })
506     }
507 
take_bin_signing_time<S: decode::Source>( cons: &mut decode::Constructed<S>, bin_signing_time: &mut Option<u64> ) -> Result<(), S::Err>508     fn take_bin_signing_time<S: decode::Source>(
509         cons: &mut decode::Constructed<S>,
510         bin_signing_time: &mut Option<u64>
511     ) -> Result<(), S::Err> {
512         update_once(bin_signing_time, || {
513             cons.take_set(|cons| cons.take_u64())
514         })
515     }
516 
encode_ref(&self) -> impl encode::Values + '_517     pub fn encode_ref(&self) -> impl encode::Values + '_ {
518         encode::sequence_as(Tag::CTX_0, &self.0)
519     }
520 
521     /// Creates the message for verification.
encode_verify(&self) -> Vec<u8>522     pub fn encode_verify(&self) -> Vec<u8> {
523         let len = self.0.len();
524         let mut res = Vec::with_capacity(len + 4);
525         res.push(0x31); // SET
526         if len < 128 {
527             res.push(len as u8)
528         }
529         else if len < 0x10000 {
530             res.push(2);
531             res.push((len >> 8) as u8);
532             res.push(len as u8);
533         }
534         else {
535             panic!("overly long signed attrs");
536         }
537         res.extend_from_slice(self.0.as_ref());
538         res
539     }
540 }
541 
542 impl AsRef<[u8]> for SignedAttrs {
as_ref(&self) -> &[u8]543     fn as_ref(&self) -> &[u8] {
544         self.0.as_ref()
545     }
546 }
547 
548 
549 //------------ MessageDigest -------------------------------------------------
550 
551 /// A private helper type that contains the message digest attribute.
552 #[derive(Clone, Debug)]
553 pub struct MessageDigest(Bytes);
554 
555 impl MessageDigest {
encode_ref(&self) -> impl encode::Values + '_556     pub fn encode_ref(&self) -> impl encode::Values + '_ {
557         OctetString::encode_slice(self.0.as_ref())
558     }
559 }
560 
561 impl From<OctetString> for MessageDigest {
from(src: OctetString) -> Self562     fn from(src: OctetString) -> Self {
563         MessageDigest(src.into_bytes())
564     }
565 }
566 
567 impl From<Digest> for MessageDigest {
from(digest: Digest) -> Self568     fn from(digest: Digest) -> Self {
569         MessageDigest(Bytes::copy_from_slice(digest.as_ref()))
570     }
571 }
572 
573 impl AsRef<[u8]> for MessageDigest {
as_ref(&self) -> &[u8]574     fn as_ref(&self) -> &[u8] {
575         self.0.as_ref()
576     }
577 }
578 
579 
580 //------------ SignedObjectBuilder -------------------------------------------
581 
582 #[derive(Clone, Debug)]
583 pub struct SignedObjectBuilder {
584     /// The digest algorithm to be used for the message digest attribute.
585     ///
586     /// By default, this will be the default algorithm.
587     digest_algorithm: DigestAlgorithm,
588 
589     /// The serial number of the EE certificate.
590     ///
591     /// Must be provided.
592     serial_number: Serial,
593 
594     /// The validity of the EE certificate.
595     ///
596     /// Must be provided.
597     validity: Validity,
598 
599     /// The issuer name of the EE certificate.
600     ///
601     /// If this is `None` (the default), it will be generated from the key
602     /// identifier of the EE certificate’s key.
603     issuer: Option<Name>,
604 
605     /// The subject name of the EE certificate.
606     ///
607     /// If this is `None` (the default), it will be generated from the key
608     /// identifier of the EE certificate’s key.
609     subject: Option<Name>,
610 
611     /// The URI of CRL for the EE certificate.
612     ///
613     /// Must be provided.
614     crl_uri: uri::Rsync,
615 
616     /// The URI of the CA certificate issuing the EE certificate.
617     ///
618     /// Must be provided.
619     ca_issuer: uri::Rsync,
620 
621     /// The URI of the signed object itself.
622     ///
623     /// Must be provided.
624     signed_object: uri::Rsync,
625 
626     /// The IPv4 resources of the EE certificate.
627     ///
628     /// Defaults to not having any.
629     v4_resources: IpResources,
630 
631     /// The IPv6 resources of the EE certificate.
632     ///
633     /// Defaults to not having any.
634     v6_resources: IpResources,
635 
636     /// The AS resources of the EE certificate.
637     ///
638     /// Defaults to not having any.
639     as_resources: AsResources,
640 
641     /// The signing time attribute of the signed object.
642     ///
643     /// This is optional and by default omitted.
644     signing_time: Option<Time>,
645 
646     /// The binary signing time attribute of the signed object.
647     ///
648     /// This is optional and by default omitted.
649     binary_signing_time: Option<u64>,
650 }
651 
652 impl SignedObjectBuilder {
new( serial_number: Serial, validity: Validity, crl_uri: uri::Rsync, ca_issuer: uri::Rsync, signed_object: uri::Rsync ) -> Self653     pub fn new(
654         serial_number: Serial,
655         validity: Validity,
656         crl_uri: uri::Rsync,
657         ca_issuer: uri::Rsync,
658         signed_object: uri::Rsync
659     ) -> Self {
660         Self {
661             digest_algorithm: DigestAlgorithm::default(),
662             serial_number,
663             validity,
664             issuer: None,
665             subject: None,
666             crl_uri,
667             ca_issuer,
668             signed_object,
669             v4_resources: IpResources::missing(),
670             v6_resources: IpResources::missing(),
671             as_resources: AsResources::missing(),
672             signing_time: None,
673             binary_signing_time: None,
674         }
675     }
676 
digest_algorithm(&self) -> DigestAlgorithm677     pub fn digest_algorithm(&self) -> DigestAlgorithm {
678         self.digest_algorithm
679     }
680 
set_digest_algorithm(&mut self, algorithm: DigestAlgorithm)681     pub fn set_digest_algorithm(&mut self, algorithm: DigestAlgorithm) {
682         self.digest_algorithm = algorithm
683     }
684 
serial_number(&self) -> Serial685     pub fn serial_number(&self) -> Serial {
686         self.serial_number
687     }
688 
set_serial_number(&mut self, serial: Serial)689     pub fn set_serial_number(&mut self, serial: Serial) {
690         self.serial_number = serial
691     }
692 
validity(&self) -> Validity693     pub fn validity(&self) -> Validity {
694         self.validity
695     }
696 
set_validity(&mut self, validity: Validity)697     pub fn set_validity(&mut self, validity: Validity) {
698         self.validity = validity
699     }
700 
issuer(&self) -> Option<&Name>701     pub fn issuer(&self) -> Option<&Name> {
702         self.issuer.as_ref()
703     }
704 
set_issuer(&mut self, name: Option<Name>)705     pub fn set_issuer(&mut self, name: Option<Name>) {
706         self.issuer = name
707     }
708 
subject(&self) -> Option<&Name>709     pub fn subject(&self) -> Option<&Name> {
710         self.subject.as_ref()
711     }
712 
set_subject(&mut self, name: Option<Name>)713     pub fn set_subject(&mut self, name: Option<Name>) {
714         self.subject = name
715     }
716 
crl_uri(&self) -> &uri::Rsync717     pub fn crl_uri(&self) -> &uri::Rsync {
718         &self.crl_uri
719     }
720 
set_crl_uri(&mut self, uri: uri::Rsync)721     pub fn set_crl_uri(&mut self, uri: uri::Rsync) {
722         self.crl_uri = uri
723     }
724 
ca_issuer(&self) -> &uri::Rsync725     pub fn ca_issuer(&self) -> &uri::Rsync {
726         &self.ca_issuer
727     }
728 
set_ca_issuer(&mut self, uri: uri::Rsync)729     pub fn set_ca_issuer(&mut self, uri: uri::Rsync) {
730         self.ca_issuer = uri
731     }
732 
signed_object(&self) -> &uri::Rsync733     pub fn signed_object(&self) -> &uri::Rsync {
734         &self.signed_object
735     }
736 
set_signed_object(&mut self, uri: uri::Rsync)737     pub fn set_signed_object(&mut self, uri: uri::Rsync) {
738         self.signed_object = uri
739     }
740 
741     /// Returns a reference to the IPv4 address resources if present.
v4_resources(&self) -> &IpResources742     pub fn v4_resources(&self) -> &IpResources {
743         &self.v4_resources
744     }
745 
746     /// Set the IPv4 address resources.
set_v4_resources(&mut self, resources: IpResources)747     pub fn set_v4_resources(&mut self, resources: IpResources) {
748         self.v4_resources = resources
749     }
750 
751     /// Sets the IPv4 address resources to inherit.
set_v4_resources_inherit(&mut self)752     pub fn set_v4_resources_inherit(&mut self) {
753         self.set_v4_resources(IpResources::inherit())
754     }
755 
756     /// Builds the blocks IPv4 address resources.
build_v4_resource_blocks<F>(&mut self, op: F) where F: FnOnce(&mut IpBlocksBuilder)757     pub fn build_v4_resource_blocks<F>(&mut self, op: F)
758     where F: FnOnce(&mut IpBlocksBuilder) {
759         let mut builder = IpResourcesBuilder::new();
760         builder.blocks(op);
761         self.set_v4_resources(builder.finalize())
762     }
763 
764     /// Returns a reference to the IPv6 address resources if present.
v6_resources(&self) -> &IpResources765     pub fn v6_resources(&self) -> &IpResources {
766         &self.v6_resources
767     }
768 
769     /// Set the IPv6 address resources.
set_v6_resources(&mut self, resources: IpResources)770     pub fn set_v6_resources(&mut self, resources: IpResources) {
771         self.v6_resources = resources
772     }
773 
774     /// Sets the IPv6 address resources to inherit.
set_v6_resources_inherit(&mut self)775     pub fn set_v6_resources_inherit(&mut self) {
776         self.set_v6_resources(IpResources::inherit())
777     }
778 
779     /// Builds the blocks IPv6 address resources.
build_v6_resource_blocks<F>(&mut self, op: F) where F: FnOnce(&mut IpBlocksBuilder)780     pub fn build_v6_resource_blocks<F>(&mut self, op: F)
781     where F: FnOnce(&mut IpBlocksBuilder) {
782         let mut builder = IpResourcesBuilder::new();
783         builder.blocks(op);
784         self.set_v6_resources(builder.finalize())
785     }
786 
787     /// Returns whether the certificate has any IP resources at all.
has_ip_resources(&self) -> bool788     pub fn has_ip_resources(&self) -> bool {
789         self.v4_resources.is_present() || self.v6_resources().is_present()
790     }
791 
792     /// Returns a reference to the AS resources if present.
as_resources(&self) -> &AsResources793     pub fn as_resources(&self) -> &AsResources {
794         &self.as_resources
795     }
796 
797     /// Set the AS resources.
set_as_resources(&mut self, resources: AsResources)798     pub fn set_as_resources(&mut self, resources: AsResources) {
799         self.as_resources = resources
800     }
801 
802     /// Sets the AS resources to inherit.
set_as_resources_inherit(&mut self)803     pub fn set_as_resources_inherit(&mut self) {
804         self.set_as_resources(AsResources::inherit())
805     }
806 
807     /// Builds the blocks AS resources.
build_as_resource_blocks<F>(&mut self, op: F) where F: FnOnce(&mut AsBlocksBuilder)808     pub fn build_as_resource_blocks<F>(&mut self, op: F)
809     where F: FnOnce(&mut AsBlocksBuilder) {
810         let mut builder = AsResourcesBuilder::new();
811         builder.blocks(op);
812         self.set_as_resources(builder.finalize())
813     }
814 
815     /// Returns the signing time attribute.
signing_time(&self) -> Option<Time>816     pub fn signing_time(&self) -> Option<Time> {
817         self.signing_time
818     }
819 
820     /// Sets the signing time attribute.
set_signing_time(&mut self, signing_time: Option<Time>)821     pub fn set_signing_time(&mut self, signing_time: Option<Time>) {
822         self.signing_time = signing_time
823     }
824 
825     /// Returns the binary signing time attribute.
binary_signing_time(&self) -> Option<u64>826     pub fn binary_signing_time(&self) -> Option<u64> {
827         self.binary_signing_time
828     }
829 
830     /// Sets the binary signing time attribute.
set_binary_signing_time(&mut self, time: Option<u64>)831     pub fn set_binary_signing_time(&mut self, time: Option<u64>) {
832         self.binary_signing_time = time
833     }
834 
finalize<S: Signer>( self, content_type: Oid<Bytes>, content: Bytes, signer: &S, issuer_key: &S::KeyId, ) -> Result<SignedObject, SigningError<S::Error>>835     pub fn finalize<S: Signer>(
836         self,
837         content_type: Oid<Bytes>,
838         content: Bytes,
839         signer: &S,
840         issuer_key: &S::KeyId,
841     ) -> Result<SignedObject, SigningError<S::Error>> {
842         let issuer_pub = signer.get_key_info(issuer_key)?;
843 
844         // Produce signed attributes.
845         let message_digest = self.digest_algorithm.digest(&content).into();
846         let signed_attrs = SignedAttrs::new(
847             &content_type,
848             &message_digest,
849             self.signing_time,
850             self.binary_signing_time
851         );
852 
853         // Sign signed attributes with a one-off key.
854         let (signature, key_info) = signer.sign_one_off(
855             SignatureAlgorithm::default(), &signed_attrs.encode_verify()
856         )?;
857         let sid = KeyIdentifier::from_public_key(&key_info);
858 
859         // Make the certificate.
860         let mut cert = TbsCert::new(
861             self.serial_number,
862             self.issuer.unwrap_or_else(|| issuer_pub.to_subject_name()),
863             self.validity,
864             self.subject,
865             key_info,
866             KeyUsage::Ee,
867             Overclaim::Refuse,
868         );
869         cert.set_authority_key_identifier(Some(issuer_pub.key_identifier()));
870         cert.set_crl_uri(Some(self.crl_uri));
871         cert.set_ca_issuer(Some(self.ca_issuer));
872         cert.set_signed_object(Some(self.signed_object));
873         cert.set_v4_resources(self.v4_resources);
874         cert.set_v6_resources(self.v6_resources);
875         cert.set_as_resources(self.as_resources);
876         let cert = cert.into_cert(signer, issuer_key)?;
877 
878         Ok(SignedObject {
879             digest_algorithm: self.digest_algorithm,
880             content_type,
881             content: OctetString::new(content),
882             cert,
883             sid,
884             signed_attrs,
885             signature,
886             message_digest,
887             signing_time: self.signing_time,
888             binary_signing_time: self.binary_signing_time,
889         })
890     }
891 }
892 
893 
894 //------------ StartOfValue --------------------------------------------------
895 
896 /// Helper type for ordering signed attributes.
897 ///
898 /// It keeps the first eight octets of a value which should be enough to
899 /// cover the length.
900 #[derive(Clone, Copy, Debug)]
901 struct StartOfValue {
902     res: [u8; 8],
903     pos: usize,
904 }
905 
906 impl StartOfValue {
new<V: encode::Values>(values: &V) -> Self907     fn new<V: encode::Values>(values: &V) -> Self {
908         let mut res = StartOfValue {
909             res: [0; 8],
910             pos: 0
911         };
912         values.write_encoded(Mode::Der, &mut res).unwrap();
913         res
914     }
915 
unwrap(self) -> [u8; 8]916     fn unwrap(self) -> [u8; 8] {
917         self.res
918     }
919 }
920 
921 impl io::Write for StartOfValue {
write(&mut self, buf: &[u8]) -> Result<usize, io::Error>922     fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
923         let slice = &mut self.res[self.pos..];
924         let len = cmp::min(slice.len(), buf.len());
925         slice[..len].copy_from_slice(&buf[..len]);
926         self.pos += len;
927         Ok(buf.len())
928     }
929 
flush(&mut self) -> Result<(), io::Error>930     fn flush(&mut self) -> Result<(), io::Error> {
931         Ok(())
932     }
933 }
934 
935 
936 //============ Tests =========================================================
937 
938 #[cfg(test)]
939 mod test {
940     use crate::repository::tal::TalInfo;
941     use super::*;
942 
943     #[test]
decode()944     fn decode() {
945         let talinfo = TalInfo::from_name("foo".into()).into_arc();
946         let at = Time::utc(2019, 5, 1, 0, 0, 0);
947         let issuer = Cert::decode(
948             include_bytes!("../../test-data/ta.cer").as_ref()
949         ).unwrap();
950         let issuer = issuer.validate_ta_at(talinfo, false, at).unwrap();
951         let obj = SignedObject::decode(
952             include_bytes!("../../test-data/ta.mft").as_ref(),
953             false
954         ).unwrap();
955         obj.validate_at(&issuer, false, at).unwrap();
956         let obj = SignedObject::decode(
957             include_bytes!("../../test-data/ca1.mft").as_ref(),
958             false
959         ).unwrap();
960         assert!(obj.validate_at(&issuer, false, at).is_err());
961     }
962 }
963 
964 #[cfg(all(test, feature="softkeys"))]
965 mod signer_test {
966     use std::str::FromStr;
967     use bcder::Oid;
968     use bcder::encode::Values;
969     use crate::uri;
970     use crate::repository::crypto::PublicKeyFormat;
971     use crate::repository::crypto::softsigner::OpenSslSigner;
972     use crate::repository::resources::{AsId, Prefix};
973     use crate::repository::tal::TalInfo;
974     use super::*;
975 
976     #[test]
encode_signed_object()977     fn encode_signed_object() {
978         let mut signer = OpenSslSigner::new();
979         let key = signer.create_key(PublicKeyFormat::Rsa).unwrap();
980         let pubkey = signer.get_key_info(&key).unwrap();
981         let uri = uri::Rsync::from_str("rsync://example.com/m/p").unwrap();
982 
983         let mut cert = TbsCert::new(
984             12u64.into(), pubkey.to_subject_name(),
985             Validity::from_secs(86400), None, pubkey, KeyUsage::Ca,
986             Overclaim::Trim
987         );
988         cert.set_basic_ca(Some(true));
989         cert.set_ca_repository(Some(uri.clone()));
990         cert.set_rpki_manifest(Some(uri.clone()));
991         cert.build_v4_resource_blocks(|b| b.push(Prefix::new(0, 0)));
992         cert.build_v6_resource_blocks(|b| b.push(Prefix::new(0, 0)));
993         cert.build_as_resource_blocks(|b| b.push((AsId::MIN, AsId::MAX)));
994         let cert = cert.into_cert(&signer, &key).unwrap();
995 
996         let mut sigobj = SignedObjectBuilder::new(
997             12u64.into(), Validity::from_secs(86400), uri.clone(),
998             uri.clone(), uri.clone()
999         );
1000         sigobj.set_v4_resources_inherit();
1001         let sigobj = sigobj.finalize(
1002             Oid(oid::SIGNED_DATA.0.into()),
1003             Bytes::from(b"1234".as_ref()),
1004             &signer,
1005             &key,
1006         ).unwrap();
1007         let sigobj = sigobj.encode_ref().to_captured(Mode::Der);
1008 
1009         let sigobj = SignedObject::decode(sigobj.as_slice(), true).unwrap();
1010         let cert = cert.validate_ta(
1011             TalInfo::from_name("foo".into()).into_arc(), true
1012         ).unwrap();
1013         sigobj.validate(&cert, true).unwrap();
1014     }
1015 }
1016 
1017 
1018 //============ Specification Documentation ===================================
1019 
1020 /// Signed Objects Specification.
1021 ///
1022 /// This is a documentation-only module. It summarizes the specification for
1023 /// signed objects, how they are to be parsed and constructed.
1024 ///
1025 /// Signed objects are CMS signed objects that have been severly limited in
1026 /// the options of the various fields. They are specified in [RFC 6488] while
1027 /// CMS is specified in [RFC 5652].
1028 ///
1029 /// A signed object is a CMS object with a single signed data object in it.
1030 ///
1031 /// A CMS object is:
1032 ///
1033 /// ```txt
1034 /// ContentInfo             ::= SEQUENCE {
1035 ///     contentType             ContentType,
1036 ///     content                 [0] EXPLICIT ANY DEFINED BY contentType }
1037 /// ```
1038 ///
1039 /// For a signed object, the _contentType_ must be `oid::SIGNED_DATA` and the
1040 /// _content_ a _SignedData_ object (however, note the `[0] EXPLICIT` there)
1041 /// as follows:
1042 ///
1043 /// ```txt
1044 /// SignedData              ::= SEQUENCE {
1045 ///     version                 CMSVersion,
1046 ///     digestAlgorithms        DigestAlgorithmIdentifiers,
1047 ///     encapContentInfo        EncapsulatedContentInfo,
1048 ///     certificates            [0] IMPLICIT CertificateSet OPTIONAL,
1049 ///     crls                    [1] IMPLICIT RevocationInfoChoices OPTIONAL,
1050 ///     signerInfos             SignerInfos }
1051 ///
1052 /// EncapsulatedContentInfo ::= SEQUENCE {
1053 ///     eContentType            ContentType,
1054 ///     eContent                [0] EXPLICIT OCTET STRING OPTIONAL }
1055 ///
1056 /// CertificateSet          ::= SET OF CertificateChoices
1057 ///
1058 /// CertificateChoices      ::= CHOICE {
1059 ///     certificate             Certificate,
1060 ///     extendedCertificate     [0] IMPLICIT ExtendedCertificate,   -- Obsolete
1061 ///     v1AttrCert              [1] IMPLICIT AttributeCertificateV1,-- Obsolete
1062 ///     v2AttrCert              [2] IMPLICIT AttributeCertificateV2,
1063 ///     other                   [3] IMPLICIT OtherCertificateFormat }
1064 /// ```
1065 ///
1066 /// Limitations imposed by [RFC 6488] are as follows:
1067 ///
1068 /// * The _version_ must be 3.
1069 /// * The _digestAlgorithms_ set must be exactly one algorithm chosen from
1070 ///   those defined in [RFC 7935]. The [`DigestAlgorithm`] type implements
1071 ///   both the _DigestAlgorithmIdentifier_ and _DigestAlgorithmIndentifiers_
1072 ///   definitions (the latter via `take_set_from` and `encode_set`).
1073 /// * The _eContentType_ field of _encapContentInfo_ defines the type of an
1074 ///   object. Check the specific signed objects for their matching object ID.
1075 /// * The _eContent_ field of _encapContentInfo_ must be present and contain
1076 ///   the actual content of the signed object.
1077 /// * There must be exactly one certificate in the `certificates` set. It must
1078 ///   be of the _certificate_ choice (that’s not exactly in RFC 6488, but it
1079 ///   is the only logical choice for ‘the RPKI end-entity (EE) certificate
1080 ///   needed to validate this signed object’), which in practice means it is
1081 ///   just one [`Cert`].
1082 /// * The _crls_ field must be omitted.
1083 ///
1084 /// The _SignerInfos_ structure:
1085 ///
1086 /// ```txt
1087 ///
1088 /// SignerInfos             ::= SET OF SignerInfo
1089 ///
1090 /// SignerInfo              ::= SEQUENCE {
1091 ///     version                 CMSVersion,
1092 ///     sid                     SignerIdentifier,
1093 ///     digestAlgorithm         DigestAlgorithmIdentifier,
1094 ///     signedAttrs             [0] IMPLICIT SignedAttributes OPTIONAL,
1095 ///     signatureAlgorithm      SignatureAlgorithmIdentifier,
1096 ///     signature               SignatureValue,
1097 ///     unsignedAttrs           [1] IMPLICIT UnsignedAttributes OPTIONAL }
1098 ///
1099 /// SignerIdentifier        ::= CHOICE {
1100 ///     issuerAndSerialNumber   IssuerAndSerialNumber,
1101 ///     subjectKeyIdentifier    [0] EXPLICIT SubjectKeyIdentifier }
1102 ///
1103 /// SubjectKeyIdentifier    ::= OCTET STRING
1104 ///
1105 /// SignatureValue          ::= OCTET STRING
1106 /// ```
1107 ///
1108 /// Limitations are as follows:
1109 ///
1110 /// * There must be exactly one _SignerInfo_ present.
1111 /// * The _version_ must be 3.
1112 /// * The _sid_ must be identical to the value of the Subject Key Identifier
1113 ///   extension of the included certificate. I.e., it must be the second
1114 ///   choice.
1115 /// * The _digestAlgorithm_ must be the same as the only value in the outer
1116 ///   _digestAlgorthm_ field.
1117 /// * The _signedAttrs_ field must be present. See below.
1118 /// * For the content of the _signature_ field, see below.
1119 /// * The _unsignedAttrs_ field must be omitted.
1120 ///
1121 /// Finally, _SignedAttributes_ is a sequence of attributes keyed by an OID.
1122 /// RPKI has two mandatory and two optional attributes. Definition for all
1123 /// of these is the following:
1124 ///
1125 /// ```text
1126 /// SignedAttributes        ::= SET SIZE (1..MAX) OF Attribute
1127 ///
1128 /// Attribute               ::= SEQUENCE {
1129 ///     attrType                OBJECT IDENTIFIER,
1130 ///     attrValues              SET OF AttributeValue }
1131 ///
1132 /// ContentType             ::= OBJECT IDENTIFIER
1133 ///
1134 /// MessageDigest           ::= OCTET STRING
1135 ///
1136 /// SigningTime             ::= Time
1137 ///
1138 /// Time                    ::= CHOICE {
1139 ///     utcTime                 UTCTime,
1140 ///     generalizedTime         GeneralizedTime }
1141 ///
1142 /// BinarySigningTime       ::= BinaryTime
1143 ///
1144 /// BinaryTime              ::= INTEGER (0..MAX)
1145 /// ```
1146 ///
1147 /// The two mandatory attributes are _ContentType_ and _MessageDigest_. The
1148 /// content type attribute must be the same as the _eContentType_ field of
1149 /// the _encapContentInfo_. The message digest attribute contains the digest
1150 /// value of the (actual) content.
1151 ///
1152 /// The _SigningTime_ and _BinarySigningTime_ attributes are optional. Their
1153 /// presence is not considered when validating a signed object.
1154 ///
1155 /// No other attribute may be present.
1156 ///
1157 /// For the object identifiers of the attributes, see the [`oid`] module.
1158 ///
1159 /// The _signature_ field of the signed object contains a signature over the
1160 /// DER encoding of the _signedAttrs_ field. When calculating the signature,
1161 /// the normal tag for the SET is used instead of the implicit `[0]`.
1162 ///
1163 /// [RFC 5652]: https://tools.ietf.org/html/rfc5652
1164 /// [RFC 6488]: https://tools.ietf.org/html/rfc6488
1165 /// [RFC 7935]: https://tools.ietf.org/html/rfc7935
1166 /// [`Cert`]: ../../cert/struct.Cert.html
1167 /// [`DigestAlgorithm`]: ../../crypto/keys/struct.DigestAlgorithm.html
1168 /// [`oid`]: ../../oid/index.html
1169 pub mod spec { }
1170 
1171 
1172