cryptographic_message_syntax/asn1/
rfc5652.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5/*! ASN.1 data structures defined by RFC 5652.
6
7The types defined in this module are intended to be extremely low-level
8and only to be used for (de)serialization. See types outside the
9`asn1` module tree for higher-level functionality.
10
11Some RFC 5652 types are defined in the `x509-certificate` crate, which
12this crate relies on for certificate parsing functionality.
13*/
14
15use {
16    crate::asn1::rfc3281::AttributeCertificate,
17    bcder::{
18        decode::{Constructed, DecodeError, Source},
19        encode,
20        encode::{PrimitiveContent, Values},
21        BitString, Captured, ConstOid, Integer, Mode, OctetString, Oid, Tag,
22    },
23    std::{
24        fmt::{Debug, Formatter},
25        io::Write,
26        ops::{Deref, DerefMut},
27    },
28    x509_certificate::{asn1time::*, rfc3280::*, rfc5280::*, rfc5652::*},
29};
30
31/// The data content type.
32///
33/// `id-data` in the specification.
34///
35/// 1.2.840.113549.1.7.1
36pub const OID_ID_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 1]);
37
38/// The signed-data content type.
39///
40/// 1.2.840.113549.1.7.2
41pub const OID_ID_SIGNED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 2]);
42
43/// Enveloped data content type.
44///
45/// 1.2.840.113549.1.7.3
46pub const OID_ENVELOPE_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 3]);
47
48/// Digested-data content type.
49///
50/// 1.2.840.113549.1.7.5
51pub const OID_DIGESTED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 5]);
52
53/// Encrypted-data content type.
54///
55/// 1.2.840.113549.1.7.6
56pub const OID_ENCRYPTED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 6]);
57
58/// Authenticated-data content type.
59///
60/// 1.2.840.113549.1.9.16.1.2
61pub const OID_AUTHENTICATED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 16, 1, 2]);
62
63/// Identifies the content-type attribute.
64///
65/// 1.2.840.113549.1.9.3
66pub const OID_CONTENT_TYPE: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 3]);
67
68/// Identifies the message-digest attribute.
69///
70/// 1.2.840.113549.1.9.4
71pub const OID_MESSAGE_DIGEST: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 4]);
72
73/// Identifies the signing-time attribute.
74///
75/// 1.2.840.113549.1.9.5
76pub const OID_SIGNING_TIME: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 5]);
77
78/// Identifies the countersignature attribute.
79///
80/// 1.2.840.113549.1.9.6
81pub const OID_COUNTER_SIGNATURE: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 6]);
82
83/// Content info.
84///
85/// ```ASN.1
86/// ContentInfo ::= SEQUENCE {
87///   contentType ContentType,
88///   content [0] EXPLICIT ANY DEFINED BY contentType }
89/// ```
90#[derive(Clone, Debug)]
91pub struct ContentInfo {
92    pub content_type: ContentType,
93    pub content: Captured,
94}
95
96impl PartialEq for ContentInfo {
97    fn eq(&self, other: &Self) -> bool {
98        self.content_type == other.content_type
99            && self.content.as_slice() == other.content.as_slice()
100    }
101}
102
103impl Eq for ContentInfo {}
104
105impl ContentInfo {
106    pub fn take_opt_from<S: Source>(
107        cons: &mut Constructed<S>,
108    ) -> Result<Option<Self>, DecodeError<S::Error>> {
109        cons.take_opt_sequence(|cons| Self::from_sequence(cons))
110    }
111
112    pub fn from_sequence<S: Source>(
113        cons: &mut Constructed<S>,
114    ) -> Result<Self, DecodeError<S::Error>> {
115        let content_type = ContentType::take_from(cons)?;
116        let content = cons.take_constructed_if(Tag::CTX_0, |cons| cons.capture_all())?;
117
118        Ok(Self {
119            content_type,
120            content,
121        })
122    }
123}
124
125impl Values for ContentInfo {
126    fn encoded_len(&self, mode: Mode) -> usize {
127        encode::sequence((self.content_type.encode_ref(), &self.content)).encoded_len(mode)
128    }
129
130    fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
131        encode::sequence((self.content_type.encode_ref(), &self.content))
132            .write_encoded(mode, target)
133    }
134}
135
136/// Represents signed data.
137///
138/// ASN.1 type specification:
139///
140/// ```ASN.1
141/// SignedData ::= SEQUENCE {
142///   version CMSVersion,
143///   digestAlgorithms DigestAlgorithmIdentifiers,
144///   encapContentInfo EncapsulatedContentInfo,
145///   certificates [0] IMPLICIT CertificateSet OPTIONAL,
146///   crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
147///   signerInfos SignerInfos }
148/// ```
149#[derive(Clone, Debug, Eq, PartialEq)]
150pub struct SignedData {
151    pub version: CmsVersion,
152    pub digest_algorithms: DigestAlgorithmIdentifiers,
153    pub content_info: EncapsulatedContentInfo,
154    pub certificates: Option<CertificateSet>,
155    pub crls: Option<RevocationInfoChoices>,
156    pub signer_infos: SignerInfos,
157}
158
159impl SignedData {
160    /// Attempt to decode BER encoded bytes to a parsed data structure.
161    pub fn decode_ber(data: &[u8]) -> Result<Self, DecodeError<std::convert::Infallible>> {
162        Constructed::decode(data, bcder::Mode::Ber, Self::decode)
163    }
164
165    pub fn decode<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
166        cons.take_sequence(|cons| {
167            let oid = Oid::take_from(cons)?;
168
169            if oid != OID_ID_SIGNED_DATA {
170                return Err(cons.content_err("expected signed data OID"));
171            }
172
173            cons.take_constructed_if(Tag::CTX_0, Self::take_from)
174        })
175    }
176
177    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
178        cons.take_sequence(|cons| {
179            let version = CmsVersion::take_from(cons)?;
180            let digest_algorithms = DigestAlgorithmIdentifiers::take_from(cons)?;
181            let content_info = EncapsulatedContentInfo::take_from(cons)?;
182            let certificates =
183                cons.take_opt_constructed_if(Tag::CTX_0, |cons| CertificateSet::take_from(cons))?;
184            let crls = cons.take_opt_constructed_if(Tag::CTX_1, |cons| {
185                RevocationInfoChoices::take_from(cons)
186            })?;
187            let signer_infos = SignerInfos::take_from(cons)?;
188
189            Ok(Self {
190                version,
191                digest_algorithms,
192                content_info,
193                certificates,
194                crls,
195                signer_infos,
196            })
197        })
198    }
199
200    pub fn encode_ref(&self) -> impl Values + '_ {
201        encode::sequence((
202            OID_ID_SIGNED_DATA.encode_ref(),
203            encode::sequence_as(
204                Tag::CTX_0,
205                encode::sequence((
206                    self.version.encode(),
207                    self.digest_algorithms.encode_ref(),
208                    self.content_info.encode_ref(),
209                    self.certificates
210                        .as_ref()
211                        .map(|certs| certs.encode_ref_as(Tag::CTX_0)),
212                    // TODO crls.
213                    self.signer_infos.encode_ref(),
214                )),
215            ),
216        ))
217    }
218}
219
220/// Digest algorithm identifiers.
221///
222/// ```ASN.1
223/// DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
224/// ```
225#[derive(Clone, Debug, Default, Eq, PartialEq)]
226pub struct DigestAlgorithmIdentifiers(Vec<DigestAlgorithmIdentifier>);
227
228impl Deref for DigestAlgorithmIdentifiers {
229    type Target = Vec<DigestAlgorithmIdentifier>;
230
231    fn deref(&self) -> &Self::Target {
232        &self.0
233    }
234}
235
236impl DerefMut for DigestAlgorithmIdentifiers {
237    fn deref_mut(&mut self) -> &mut Self::Target {
238        &mut self.0
239    }
240}
241
242impl DigestAlgorithmIdentifiers {
243    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
244        cons.take_set(|cons| {
245            let mut identifiers = Vec::new();
246
247            while let Some(identifier) = AlgorithmIdentifier::take_opt_from(cons)? {
248                identifiers.push(identifier);
249            }
250
251            Ok(Self(identifiers))
252        })
253    }
254
255    pub fn encode_ref(&self) -> impl Values + '_ {
256        encode::set(&self.0)
257    }
258}
259
260pub type DigestAlgorithmIdentifier = AlgorithmIdentifier;
261
262/// Signer infos.
263///
264/// ```ASN.1
265/// SignerInfos ::= SET OF SignerInfo
266/// ```
267#[derive(Clone, Debug, Default, Eq, PartialEq)]
268pub struct SignerInfos(Vec<SignerInfo>);
269
270impl Deref for SignerInfos {
271    type Target = Vec<SignerInfo>;
272
273    fn deref(&self) -> &Self::Target {
274        &self.0
275    }
276}
277
278impl DerefMut for SignerInfos {
279    fn deref_mut(&mut self) -> &mut Self::Target {
280        &mut self.0
281    }
282}
283
284impl SignerInfos {
285    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
286        cons.take_set(|cons| {
287            let mut infos = Vec::new();
288
289            while let Some(info) = SignerInfo::take_opt_from(cons)? {
290                infos.push(info);
291            }
292
293            Ok(Self(infos))
294        })
295    }
296
297    pub fn encode_ref(&self) -> impl Values + '_ {
298        encode::set(&self.0)
299    }
300}
301
302/// Encapsulated content info.
303///
304/// ```ASN.1
305/// EncapsulatedContentInfo ::= SEQUENCE {
306///   eContentType ContentType,
307///   eContent [0] EXPLICIT OCTET STRING OPTIONAL }
308/// ```
309#[derive(Clone, Eq, PartialEq)]
310pub struct EncapsulatedContentInfo {
311    pub content_type: ContentType,
312    pub content: Option<OctetString>,
313}
314
315impl Debug for EncapsulatedContentInfo {
316    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
317        let mut s = f.debug_struct("EncapsulatedContentInfo");
318        s.field("content_type", &format_args!("{}", self.content_type));
319        s.field(
320            "content",
321            &format_args!(
322                "{:?}",
323                self.content
324                    .as_ref()
325                    .map(|x| hex::encode(x.clone().to_bytes().as_ref()))
326            ),
327        );
328        s.finish()
329    }
330}
331
332impl EncapsulatedContentInfo {
333    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
334        cons.take_sequence(|cons| {
335            let content_type = ContentType::take_from(cons)?;
336            let content =
337                cons.take_opt_constructed_if(Tag::CTX_0, |cons| OctetString::take_from(cons))?;
338
339            Ok(Self {
340                content_type,
341                content,
342            })
343        })
344    }
345
346    pub fn encode_ref(&self) -> impl Values + '_ {
347        encode::sequence((
348            self.content_type.encode_ref(),
349            self.content
350                .as_ref()
351                .map(|content| encode::sequence_as(Tag::CTX_0, content.encode_ref())),
352        ))
353    }
354}
355
356/// Per-signer information.
357///
358/// ```ASN.1
359/// SignerInfo ::= SEQUENCE {
360///   version CMSVersion,
361///   sid SignerIdentifier,
362///   digestAlgorithm DigestAlgorithmIdentifier,
363///   signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
364///   signatureAlgorithm SignatureAlgorithmIdentifier,
365///   signature SignatureValue,
366///   unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
367/// ```
368#[derive(Clone, Eq, PartialEq)]
369pub struct SignerInfo {
370    pub version: CmsVersion,
371    pub sid: SignerIdentifier,
372    pub digest_algorithm: DigestAlgorithmIdentifier,
373    pub signed_attributes: Option<SignedAttributes>,
374    pub signature_algorithm: SignatureAlgorithmIdentifier,
375    pub signature: SignatureValue,
376    pub unsigned_attributes: Option<UnsignedAttributes>,
377
378    /// Raw bytes backing signed attributes data.
379    ///
380    /// Does not include constructed tag or length bytes.
381    pub signed_attributes_data: Option<Vec<u8>>,
382}
383
384impl SignerInfo {
385    pub fn take_opt_from<S: Source>(
386        cons: &mut Constructed<S>,
387    ) -> Result<Option<Self>, DecodeError<S::Error>> {
388        cons.take_opt_sequence(|cons| Self::from_sequence(cons))
389    }
390
391    pub fn from_sequence<S: Source>(
392        cons: &mut Constructed<S>,
393    ) -> Result<Self, DecodeError<S::Error>> {
394        let version = CmsVersion::take_from(cons)?;
395        let sid = SignerIdentifier::take_from(cons)?;
396        let digest_algorithm = DigestAlgorithmIdentifier::take_from(cons)?;
397        let signed_attributes = cons.take_opt_constructed_if(Tag::CTX_0, |cons| {
398            // RFC 5652 Section 5.3: SignedAttributes MUST be DER encoded, even if the
399            // rest of the structure is BER encoded. So buffer all data so we can
400            // feed into a new decoder.
401            let der = cons.capture_all()?;
402
403            // But wait there's more! The raw data constituting the signed
404            // attributes is also digested and used for content/signature
405            // verification. Because our DER serialization may not roundtrip
406            // losslessly, we stash away a copy of these bytes so they may be
407            // referenced as part of verification.
408            let der_data = der.as_slice().to_vec();
409
410            Ok((
411                Constructed::decode(der.as_slice(), bcder::Mode::Der, |cons| {
412                    SignedAttributes::take_from_set(cons)
413                })
414                .map_err(|e| e.convert())?,
415                der_data,
416            ))
417        })?;
418
419        let (signed_attributes, signed_attributes_data) = if let Some((x, y)) = signed_attributes {
420            (Some(x), Some(y))
421        } else {
422            (None, None)
423        };
424
425        let signature_algorithm = SignatureAlgorithmIdentifier::take_from(cons)?;
426        let signature = SignatureValue::take_from(cons)?;
427        let unsigned_attributes = cons
428            .take_opt_constructed_if(Tag::CTX_1, |cons| UnsignedAttributes::take_from_set(cons))?;
429
430        Ok(Self {
431            version,
432            sid,
433            digest_algorithm,
434            signed_attributes,
435            signature_algorithm,
436            signature,
437            unsigned_attributes,
438            signed_attributes_data,
439        })
440    }
441
442    pub fn encode_ref(&self) -> impl Values + '_ {
443        encode::sequence((
444            u8::from(self.version).encode(),
445            &self.sid,
446            &self.digest_algorithm,
447            // Always write signed attributes with DER encoding per RFC 5652.
448            self.signed_attributes
449                .as_ref()
450                .map(|attrs| SignedAttributesDer::new(attrs.clone(), Some(Tag::CTX_0))),
451            &self.signature_algorithm,
452            self.signature.encode_ref(),
453            self.unsigned_attributes
454                .as_ref()
455                .map(|attrs| attrs.encode_ref_as(Tag::CTX_1)),
456        ))
457    }
458
459    /// Obtain content representing the signed attributes data to be digested.
460    ///
461    /// Computing the content to go into the digest calculation is nuanced.
462    /// From RFC 5652:
463    ///
464    ///    The result of the message digest calculation process depends on
465    ///    whether the signedAttrs field is present.  When the field is absent,
466    ///    the result is just the message digest of the content as described
467    ///    above.  When the field is present, however, the result is the message
468    ///    digest of the complete DER encoding of the SignedAttrs value
469    ///    contained in the signedAttrs field.  Since the SignedAttrs value,
470    ///    when present, must contain the content-type and the message-digest
471    ///    attributes, those values are indirectly included in the result.  The
472    ///    content-type attribute MUST NOT be included in a countersignature
473    ///    unsigned attribute as defined in Section 11.4.  A separate encoding
474    ///    of the signedAttrs field is performed for message digest calculation.
475    ///    The `IMPLICIT [0]` tag in the signedAttrs is not used for the DER
476    ///    encoding, rather an EXPLICIT SET OF tag is used.  That is, the DER
477    ///    encoding of the EXPLICIT SET OF tag, rather than of the `IMPLICIT [0]`
478    ///    tag, MUST be included in the message digest calculation along with
479    ///    the length and content octets of the SignedAttributes value.
480    ///
481    /// A few things to note here:
482    ///
483    /// * We must ensure DER (not BER) encoding of the entire SignedAttrs values.
484    /// * The SignedAttr tag must use `EXPLICIT SET OF` instead of `IMPLICIT [0]`,
485    ///   so default encoding is not appropriate.
486    /// * If this instance came into existence via a parse, we stashed away the
487    ///   raw bytes constituting SignedAttributes to ensure we can do a lossless
488    ///   copy.
489    pub fn signed_attributes_digested_content(&self) -> Result<Option<Vec<u8>>, std::io::Error> {
490        if let Some(signed_attributes) = &self.signed_attributes {
491            if let Some(existing_data) = &self.signed_attributes_data {
492                // +8 should be enough for tag + length.
493                let mut buffer = Vec::with_capacity(existing_data.len() + 8);
494                // EXPLICIT SET OF.
495                buffer.write_all(&[0x31])?;
496
497                // Length isn't exported by bcder :/ So do length encoding manually.
498                if existing_data.len() < 0x80 {
499                    buffer.write_all(&[existing_data.len() as u8])?;
500                } else if existing_data.len() < 0x100 {
501                    buffer.write_all(&[0x81, existing_data.len() as u8])?;
502                } else if existing_data.len() < 0x10000 {
503                    buffer.write_all(&[
504                        0x82,
505                        (existing_data.len() >> 8) as u8,
506                        existing_data.len() as u8,
507                    ])?;
508                } else if existing_data.len() < 0x1000000 {
509                    buffer.write_all(&[
510                        0x83,
511                        (existing_data.len() >> 16) as u8,
512                        (existing_data.len() >> 8) as u8,
513                        existing_data.len() as u8,
514                    ])?;
515                } else {
516                    return Err(std::io::Error::new(
517                        std::io::ErrorKind::InvalidData,
518                        "signed attributes length too long",
519                    ));
520                }
521
522                buffer.write_all(existing_data)?;
523
524                Ok(Some(buffer))
525            } else {
526                // No existing copy present. Serialize from raw data structures.
527                // But we obtain a sorted instance of those attributes first, because
528                // bcder doesn't appear to follow DER encoding rules for sets.
529                let signed_attributes = signed_attributes.as_sorted()?;
530                let mut der = Vec::new();
531                // The mode argument here is actually ignored.
532                signed_attributes.write_encoded(Mode::Der, &mut der)?;
533
534                Ok(Some(der))
535            }
536        } else {
537            Ok(None)
538        }
539    }
540}
541
542impl Debug for SignerInfo {
543    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
544        let mut s = f.debug_struct("SignerInfo");
545
546        s.field("version", &self.version);
547        s.field("sid", &self.sid);
548        s.field("digest_algorithm", &self.digest_algorithm);
549        s.field("signed_attributes", &self.signed_attributes);
550        s.field("signature_algorithm", &self.signature_algorithm);
551        s.field(
552            "signature",
553            &format_args!(
554                "{}",
555                hex::encode(self.signature.clone().into_bytes().as_ref())
556            ),
557        );
558        s.field("unsigned_attributes", &self.unsigned_attributes);
559        s.field(
560            "signed_attributes_data",
561            &format_args!(
562                "{:?}",
563                self.signed_attributes_data.as_ref().map(hex::encode)
564            ),
565        );
566        s.finish()
567    }
568}
569
570impl Values for SignerInfo {
571    fn encoded_len(&self, mode: Mode) -> usize {
572        self.encode_ref().encoded_len(mode)
573    }
574
575    fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
576        self.encode_ref().write_encoded(mode, target)
577    }
578}
579
580/// Identifies the signer.
581///
582/// ```ASN.1
583/// SignerIdentifier ::= CHOICE {
584///   issuerAndSerialNumber IssuerAndSerialNumber,
585///   subjectKeyIdentifier [0] SubjectKeyIdentifier }
586#[derive(Clone, Debug, Eq, PartialEq)]
587pub enum SignerIdentifier {
588    IssuerAndSerialNumber(IssuerAndSerialNumber),
589    SubjectKeyIdentifier(SubjectKeyIdentifier),
590}
591
592impl SignerIdentifier {
593    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
594        match cons.take_opt_constructed_if(Tag::CTX_0, |cons| SubjectKeyIdentifier::take_from(cons))?
595        { Some(identifier) => {
596            Ok(Self::SubjectKeyIdentifier(identifier))
597        } _ => {
598            Ok(Self::IssuerAndSerialNumber(
599                IssuerAndSerialNumber::take_from(cons)?,
600            ))
601        }}
602    }
603}
604
605impl Values for SignerIdentifier {
606    fn encoded_len(&self, mode: Mode) -> usize {
607        match self {
608            Self::IssuerAndSerialNumber(v) => v.encode_ref().encoded_len(mode),
609            Self::SubjectKeyIdentifier(v) => v.encode_ref_as(Tag::CTX_0).encoded_len(mode),
610        }
611    }
612
613    fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
614        match self {
615            Self::IssuerAndSerialNumber(v) => v.encode_ref().write_encoded(mode, target),
616            Self::SubjectKeyIdentifier(v) => {
617                v.encode_ref_as(Tag::CTX_0).write_encoded(mode, target)
618            }
619        }
620    }
621}
622
623/// Signed attributes.
624///
625/// ```ASN.1
626/// SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
627/// ```
628#[derive(Clone, Debug, Default, Eq, PartialEq)]
629pub struct SignedAttributes(Vec<Attribute>);
630
631impl Deref for SignedAttributes {
632    type Target = Vec<Attribute>;
633
634    fn deref(&self) -> &Self::Target {
635        &self.0
636    }
637}
638
639impl DerefMut for SignedAttributes {
640    fn deref_mut(&mut self) -> &mut Self::Target {
641        &mut self.0
642    }
643}
644
645impl SignedAttributes {
646    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
647        cons.take_set(|cons| Self::take_from_set(cons))
648    }
649
650    pub fn take_from_set<S: Source>(
651        cons: &mut Constructed<S>,
652    ) -> Result<Self, DecodeError<S::Error>> {
653        let mut attributes = Vec::new();
654
655        while let Some(attribute) = Attribute::take_opt_from(cons)? {
656            attributes.push(attribute);
657        }
658
659        Ok(Self(attributes))
660    }
661
662    /// Obtain an instance where the attributes are sorted according to DER
663    /// rules. See the comment in [SignerInfo::signed_attributes_digested_content].
664    pub fn as_sorted(&self) -> Result<Self, std::io::Error> {
665        // Sorted is based on encoding of each Attribute, per DER encoding rules.
666        // The encoding is supported to be padded with 0s. But Rust will sort a
667        // shorter value with a prefix match against a longer value as less than,
668        // so we can avoid the padding.
669
670        let mut attributes = self
671            .0
672            .iter()
673            .map(|x| {
674                let mut encoded = vec![];
675                // See (https://github.com/indygreg/cryptography-rs/issues/16)
676                // The entire attribute must be encoded in order to be compared
677                // to a sibling attribute
678                x.encode_ref().write_encoded(Mode::Der, &mut encoded)?;
679
680                Ok((encoded, x.clone()))
681            })
682            .collect::<Result<Vec<(_, _)>, std::io::Error>>()?;
683
684        attributes.sort_by(|(a, _), (b, _)| a.cmp(b));
685
686        Ok(Self(
687            attributes.into_iter().map(|(_, x)| x).collect::<Vec<_>>(),
688        ))
689    }
690
691    fn encode_ref(&self) -> impl Values + '_ {
692        encode::set(encode::slice(&self.0, |x| x.clone().encode()))
693    }
694
695    fn encode_ref_as(&self, tag: Tag) -> impl Values + '_ {
696        encode::set_as(tag, encode::slice(&self.0, |x| x.clone().encode()))
697    }
698}
699
700impl Values for SignedAttributes {
701    // SignedAttributes are always written as DER encoded.
702    fn encoded_len(&self, _: Mode) -> usize {
703        self.encode_ref().encoded_len(Mode::Der)
704    }
705
706    fn write_encoded<W: Write>(&self, _: Mode, target: &mut W) -> Result<(), std::io::Error> {
707        self.encode_ref().write_encoded(Mode::Der, target)
708    }
709}
710
711pub struct SignedAttributesDer(SignedAttributes, Option<Tag>);
712
713impl SignedAttributesDer {
714    pub fn new(sa: SignedAttributes, tag: Option<Tag>) -> Self {
715        Self(sa, tag)
716    }
717}
718
719impl Values for SignedAttributesDer {
720    fn encoded_len(&self, _: Mode) -> usize {
721        if let Some(tag) = &self.1 {
722            self.0.encode_ref_as(*tag).encoded_len(Mode::Der)
723        } else {
724            self.0.encode_ref().encoded_len(Mode::Der)
725        }
726    }
727
728    fn write_encoded<W: Write>(&self, _: Mode, target: &mut W) -> Result<(), std::io::Error> {
729        if let Some(tag) = &self.1 {
730            self.0.encode_ref_as(*tag).write_encoded(Mode::Der, target)
731        } else {
732            self.0.encode_ref().write_encoded(Mode::Der, target)
733        }
734    }
735}
736
737/// Unsigned attributes.
738///
739/// ```ASN.1
740/// UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute
741/// ```
742#[derive(Clone, Debug, Default, Eq, PartialEq)]
743pub struct UnsignedAttributes(Vec<Attribute>);
744
745impl Deref for UnsignedAttributes {
746    type Target = Vec<Attribute>;
747
748    fn deref(&self) -> &Self::Target {
749        &self.0
750    }
751}
752
753impl DerefMut for UnsignedAttributes {
754    fn deref_mut(&mut self) -> &mut Self::Target {
755        &mut self.0
756    }
757}
758
759impl UnsignedAttributes {
760    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
761        cons.take_set(|cons| Self::take_from_set(cons))
762    }
763
764    pub fn take_from_set<S: Source>(
765        cons: &mut Constructed<S>,
766    ) -> Result<Self, DecodeError<S::Error>> {
767        let mut attributes = Vec::new();
768
769        while let Some(attribute) = Attribute::take_opt_from(cons)? {
770            attributes.push(attribute);
771        }
772
773        Ok(Self(attributes))
774    }
775
776    pub fn encode_ref_as(&self, tag: Tag) -> impl Values + '_ {
777        encode::set_as(tag, encode::slice(&self.0, |x| x.clone().encode()))
778    }
779}
780
781pub type SignatureValue = OctetString;
782
783/// Enveloped-data content type.
784///
785/// ```ASN.1
786/// EnvelopedData ::= SEQUENCE {
787///   version CMSVersion,
788///   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
789///   recipientInfos RecipientInfos,
790///   encryptedContentInfo EncryptedContentInfo,
791///   unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
792/// ```
793#[derive(Clone, Debug, Eq, PartialEq)]
794pub struct EnvelopedData {
795    pub version: CmsVersion,
796    pub originator_info: Option<OriginatorInfo>,
797    pub recipient_infos: RecipientInfos,
798    pub encrypted_content_info: EncryptedContentInfo,
799    pub unprotected_attributes: Option<UnprotectedAttributes>,
800}
801
802/// Originator info.
803///
804/// ```ASN.1
805/// OriginatorInfo ::= SEQUENCE {
806///   certs [0] IMPLICIT CertificateSet OPTIONAL,
807///   crls [1] IMPLICIT RevocationInfoChoices OPTIONAL }
808/// ```
809#[derive(Clone, Debug, Eq, PartialEq)]
810pub struct OriginatorInfo {
811    pub certs: Option<CertificateSet>,
812    pub crls: Option<RevocationInfoChoices>,
813}
814
815pub type RecipientInfos = Vec<RecipientInfo>;
816
817/// Encrypted content info.
818///
819/// ```ASN.1
820/// EncryptedContentInfo ::= SEQUENCE {
821///   contentType ContentType,
822///   contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
823///   encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
824/// ```
825#[derive(Clone, Debug, Eq, PartialEq)]
826pub struct EncryptedContentInfo {
827    pub content_type: ContentType,
828    pub content_encryption_algorithms: ContentEncryptionAlgorithmIdentifier,
829    pub encrypted_content: Option<EncryptedContent>,
830}
831
832pub type EncryptedContent = OctetString;
833
834pub type UnprotectedAttributes = Vec<Attribute>;
835
836/// Recipient info.
837///
838/// ```ASN.1
839/// RecipientInfo ::= CHOICE {
840///   ktri KeyTransRecipientInfo,
841///   kari [1] KeyAgreeRecipientInfo,
842///   kekri [2] KEKRecipientInfo,
843///   pwri [3] PasswordRecipientinfo,
844///   ori [4] OtherRecipientInfo }
845/// ```
846#[derive(Clone, Debug, Eq, PartialEq)]
847pub enum RecipientInfo {
848    KeyTransRecipientInfo(KeyTransRecipientInfo),
849    KeyAgreeRecipientInfo(KeyAgreeRecipientInfo),
850    KekRecipientInfo(KekRecipientInfo),
851    PasswordRecipientInfo(PasswordRecipientInfo),
852    OtherRecipientInfo(OtherRecipientInfo),
853}
854
855pub type EncryptedKey = OctetString;
856
857/// Key trans recipient info.
858///
859/// ```ASN.1
860/// KeyTransRecipientInfo ::= SEQUENCE {
861///   version CMSVersion,  -- always set to 0 or 2
862///   rid RecipientIdentifier,
863///   keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
864///   encryptedKey EncryptedKey }
865/// ```
866#[derive(Clone, Debug, Eq, PartialEq)]
867pub struct KeyTransRecipientInfo {
868    pub version: CmsVersion,
869    pub rid: RecipientIdentifier,
870    pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
871    pub encrypted_key: EncryptedKey,
872}
873
874/// Recipient identifier.
875///
876/// ```ASN.1
877/// RecipientIdentifier ::= CHOICE {
878///   issuerAndSerialNumber IssuerAndSerialNumber,
879///   subjectKeyIdentifier [0] SubjectKeyIdentifier }
880/// ```
881#[derive(Clone, Debug, Eq, PartialEq)]
882pub enum RecipientIdentifier {
883    IssuerAndSerialNumber(IssuerAndSerialNumber),
884    SubjectKeyIdentifier(SubjectKeyIdentifier),
885}
886
887/// Key agreement recipient info.
888///
889/// ```ASN.1
890/// KeyAgreeRecipientInfo ::= SEQUENCE {
891///   version CMSVersion,  -- always set to 3
892///   originator [0] EXPLICIT OriginatorIdentifierOrKey,
893///   ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
894///   keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
895///   recipientEncryptedKeys RecipientEncryptedKeys }
896/// ```
897#[derive(Clone, Debug, Eq, PartialEq)]
898pub struct KeyAgreeRecipientInfo {
899    pub version: CmsVersion,
900    pub originator: OriginatorIdentifierOrKey,
901    pub ukm: Option<UserKeyingMaterial>,
902    pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
903    pub recipient_encrypted_keys: RecipientEncryptedKeys,
904}
905
906/// Originator identifier or key.
907///
908/// ```ASN.1
909/// OriginatorIdentifierOrKey ::= CHOICE {
910///   issuerAndSerialNumber IssuerAndSerialNumber,
911///   subjectKeyIdentifier [0] SubjectKeyIdentifier,
912///   originatorKey [1] OriginatorPublicKey }
913/// ```
914#[derive(Clone, Debug, Eq, PartialEq)]
915pub enum OriginatorIdentifierOrKey {
916    IssuerAndSerialNumber(IssuerAndSerialNumber),
917    SubjectKeyIdentifier(SubjectKeyIdentifier),
918    OriginatorKey(OriginatorPublicKey),
919}
920
921/// Originator public key.
922///
923/// ```ASN.1
924/// OriginatorPublicKey ::= SEQUENCE {
925///   algorithm AlgorithmIdentifier,
926///   publicKey BIT STRING }
927/// ```
928#[derive(Clone, Debug, Eq, PartialEq)]
929pub struct OriginatorPublicKey {
930    pub algorithm: AlgorithmIdentifier,
931    pub public_key: BitString,
932}
933
934/// SEQUENCE of RecipientEncryptedKey.
935type RecipientEncryptedKeys = Vec<RecipientEncryptedKey>;
936
937/// Recipient encrypted key.
938///
939/// ```ASN.1
940/// RecipientEncryptedKey ::= SEQUENCE {
941///   rid KeyAgreeRecipientIdentifier,
942///   encryptedKey EncryptedKey }
943/// ```
944#[derive(Clone, Debug, Eq, PartialEq)]
945pub struct RecipientEncryptedKey {
946    pub rid: KeyAgreeRecipientInfo,
947    pub encrypted_key: EncryptedKey,
948}
949
950/// Key agreement recipient identifier.
951///
952/// ```ASN.1
953/// KeyAgreeRecipientIdentifier ::= CHOICE {
954///   issuerAndSerialNumber IssuerAndSerialNumber,
955///   rKeyId [0] IMPLICIT RecipientKeyIdentifier }
956/// ```
957#[derive(Clone, Debug, Eq, PartialEq)]
958pub enum KeyAgreeRecipientIdentifier {
959    IssuerAndSerialNumber(IssuerAndSerialNumber),
960    RKeyId(RecipientKeyIdentifier),
961}
962
963/// Recipient key identifier.
964///
965/// ```ASN.1
966/// RecipientKeyIdentifier ::= SEQUENCE {
967///   subjectKeyIdentifier SubjectKeyIdentifier,
968///   date GeneralizedTime OPTIONAL,
969///   other OtherKeyAttribute OPTIONAL }
970/// ```
971#[derive(Clone, Debug, Eq, PartialEq)]
972pub struct RecipientKeyIdentifier {
973    pub subject_key_identifier: SubjectKeyIdentifier,
974    pub date: Option<GeneralizedTime>,
975    pub other: Option<OtherKeyAttribute>,
976}
977
978type SubjectKeyIdentifier = OctetString;
979
980/// Key encryption key recipient info.
981///
982/// ```ASN.1
983/// KEKRecipientInfo ::= SEQUENCE {
984///   version CMSVersion,  -- always set to 4
985///   kekid KEKIdentifier,
986///   keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
987///   encryptedKey EncryptedKey }
988/// ```
989#[derive(Clone, Debug, Eq, PartialEq)]
990pub struct KekRecipientInfo {
991    pub version: CmsVersion,
992    pub kek_id: KekIdentifier,
993    pub kek_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
994    pub encrypted_key: EncryptedKey,
995}
996
997/// Key encryption key identifier.
998///
999/// ```ASN.1
1000/// KEKIdentifier ::= SEQUENCE {
1001///   keyIdentifier OCTET STRING,
1002///   date GeneralizedTime OPTIONAL,
1003///   other OtherKeyAttribute OPTIONAL }
1004/// ```
1005#[derive(Clone, Debug, Eq, PartialEq)]
1006pub struct KekIdentifier {
1007    pub key_identifier: OctetString,
1008    pub date: Option<GeneralizedTime>,
1009    pub other: Option<OtherKeyAttribute>,
1010}
1011
1012/// Password recipient info.
1013///
1014/// ```ASN.1
1015/// PasswordRecipientInfo ::= SEQUENCE {
1016///   version CMSVersion,   -- Always set to 0
1017///   keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
1018///                                OPTIONAL,
1019///   keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
1020///   encryptedKey EncryptedKey }
1021/// ```
1022#[derive(Clone, Debug, Eq, PartialEq)]
1023pub struct PasswordRecipientInfo {
1024    pub version: CmsVersion,
1025    pub key_derivation_algorithm: Option<KeyDerivationAlgorithmIdentifier>,
1026    pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
1027    pub encrypted_key: EncryptedKey,
1028}
1029
1030#[derive(Clone, Debug, Eq, PartialEq)]
1031pub struct OtherRecipientInfo {
1032    pub ori_type: Oid,
1033    // TODO Any
1034    pub ori_value: Option<()>,
1035}
1036
1037/// Digested data.
1038///
1039/// ```ASN.1
1040/// DigestedData ::= SEQUENCE {
1041///   version CMSVersion,
1042///   digestAlgorithm DigestAlgorithmIdentifier,
1043///   encapContentInfo EncapsulatedContentInfo,
1044///   digest Digest }
1045/// ```
1046#[derive(Clone, Debug, Eq, PartialEq)]
1047pub struct DigestedData {
1048    pub version: CmsVersion,
1049    pub digest_algorithm: DigestAlgorithmIdentifier,
1050    pub content_type: EncapsulatedContentInfo,
1051    pub digest: Digest,
1052}
1053
1054pub type Digest = OctetString;
1055
1056/// Encrypted data.
1057///
1058/// ```ASN.1
1059/// EncryptedData ::= SEQUENCE {
1060///   version CMSVersion,
1061///   encryptedContentInfo EncryptedContentInfo,
1062///   unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
1063/// ```
1064#[derive(Clone, Debug, Eq, PartialEq)]
1065pub struct EncryptedData {
1066    pub version: CmsVersion,
1067    pub encrypted_content_info: EncryptedContentInfo,
1068    pub unprotected_attributes: Option<UnprotectedAttributes>,
1069}
1070
1071/// Authenticated data.
1072///
1073/// ```ASN.1
1074/// AuthenticatedData ::= SEQUENCE {
1075///   version CMSVersion,
1076///   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
1077///   recipientInfos RecipientInfos,
1078///   macAlgorithm MessageAuthenticationCodeAlgorithm,
1079///   digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
1080///   encapContentInfo EncapsulatedContentInfo,
1081///   authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
1082///   mac MessageAuthenticationCode,
1083///   unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
1084/// ```
1085#[derive(Clone, Debug, Eq, PartialEq)]
1086pub struct AuthenticatedData {
1087    pub version: CmsVersion,
1088    pub originator_info: Option<OriginatorInfo>,
1089    pub recipient_infos: RecipientInfos,
1090    pub mac_algorithm: MessageAuthenticationCodeAlgorithm,
1091    pub digest_algorithm: Option<DigestAlgorithmIdentifier>,
1092    pub content_info: EncapsulatedContentInfo,
1093    pub authenticated_attributes: Option<AuthAttributes>,
1094    pub mac: MessageAuthenticationCode,
1095    pub unauthenticated_attributes: Option<UnauthAttributes>,
1096}
1097
1098pub type AuthAttributes = Vec<Attribute>;
1099
1100pub type UnauthAttributes = Vec<Attribute>;
1101
1102pub type MessageAuthenticationCode = OctetString;
1103
1104pub type SignatureAlgorithmIdentifier = AlgorithmIdentifier;
1105
1106pub type KeyEncryptionAlgorithmIdentifier = AlgorithmIdentifier;
1107
1108pub type ContentEncryptionAlgorithmIdentifier = AlgorithmIdentifier;
1109
1110pub type MessageAuthenticationCodeAlgorithm = AlgorithmIdentifier;
1111
1112pub type KeyDerivationAlgorithmIdentifier = AlgorithmIdentifier;
1113
1114/// Revocation info choices.
1115///
1116/// ```ASN.1
1117/// RevocationInfoChoices ::= SET OF RevocationInfoChoice
1118/// ```
1119#[derive(Clone, Debug, Eq, PartialEq)]
1120pub struct RevocationInfoChoices(Vec<RevocationInfoChoice>);
1121
1122impl RevocationInfoChoices {
1123    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
1124        Err(cons.content_err("RevocationInfoChoices parsing not implemented"))
1125    }
1126}
1127
1128/// Revocation info choice.
1129///
1130/// ```ASN.1
1131/// RevocationInfoChoice ::= CHOICE {
1132///   crl CertificateList,
1133///   other [1] IMPLICIT OtherRevocationInfoFormat }
1134/// ```
1135#[derive(Clone, Debug, Eq, PartialEq)]
1136pub enum RevocationInfoChoice {
1137    Crl(Box<CertificateList>),
1138    Other(OtherRevocationInfoFormat),
1139}
1140
1141/// Other revocation info format.
1142///
1143/// ```ASN.1
1144/// OtherRevocationInfoFormat ::= SEQUENCE {
1145///   otherRevInfoFormat OBJECT IDENTIFIER,
1146///   otherRevInfo ANY DEFINED BY otherRevInfoFormat }
1147/// ```
1148#[derive(Clone, Debug, Eq, PartialEq)]
1149pub struct OtherRevocationInfoFormat {
1150    pub other_rev_info_info_format: Oid,
1151    // TODO Any
1152    pub other_rev_info: Option<()>,
1153}
1154
1155/// Certificate choices.
1156///
1157/// ```ASN.1
1158/// CertificateChoices ::= CHOICE {
1159///   certificate Certificate,
1160///   extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
1161///   v1AttrCert [1] IMPLICIT AttributeCertificateV1,       -- Obsolete
1162///   v2AttrCert [2] IMPLICIT AttributeCertificateV2,
1163///   other [3] IMPLICIT OtherCertificateFormat }
1164/// ```
1165#[derive(Clone, Debug, Eq, PartialEq)]
1166pub enum CertificateChoices {
1167    Certificate(Box<Certificate>),
1168    // ExtendedCertificate(ExtendedCertificate),
1169    // AttributeCertificateV1(AttributeCertificateV1),
1170    AttributeCertificateV2(Box<AttributeCertificateV2>),
1171    Other(Box<OtherCertificateFormat>),
1172}
1173
1174impl CertificateChoices {
1175    pub fn take_opt_from<S: Source>(
1176        cons: &mut Constructed<S>,
1177    ) -> Result<Option<Self>, DecodeError<S::Error>> {
1178        cons.take_opt_constructed_if(Tag::CTX_0, |cons| -> Result<(), DecodeError<S::Error>> {
1179            Err(cons.content_err("ExtendedCertificate parsing not implemented"))
1180        })?;
1181        cons.take_opt_constructed_if(Tag::CTX_1, |cons| -> Result<(), DecodeError<S::Error>> {
1182            Err(cons.content_err("AttributeCertificateV1 parsing not implemented"))
1183        })?;
1184
1185        // TODO these first 2 need methods that parse an already entered SEQUENCE.
1186        match cons
1187            .take_opt_constructed_if(Tag::CTX_2, |cons| AttributeCertificateV2::take_from(cons))?
1188        { Some(certificate) => {
1189            Ok(Some(Self::AttributeCertificateV2(Box::new(certificate))))
1190        } _ => { match cons
1191            .take_opt_constructed_if(Tag::CTX_3, |cons| OtherCertificateFormat::take_from(cons))?
1192        { Some(certificate) => {
1193            Ok(Some(Self::Other(Box::new(certificate))))
1194        } _ => { match cons.take_opt_constructed(|_, cons| Certificate::from_sequence(cons))?
1195        { Some(certificate) => {
1196            Ok(Some(Self::Certificate(Box::new(certificate))))
1197        } _ => {
1198            Ok(None)
1199        }}}}}}
1200    }
1201
1202    pub fn encode_ref(&self) -> impl Values + '_ {
1203        match self {
1204            Self::Certificate(cert) => cert.encode_ref(),
1205            Self::AttributeCertificateV2(_) => unimplemented!(),
1206            Self::Other(_) => unimplemented!(),
1207        }
1208    }
1209}
1210
1211impl Values for CertificateChoices {
1212    fn encoded_len(&self, mode: Mode) -> usize {
1213        self.encode_ref().encoded_len(mode)
1214    }
1215
1216    fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
1217        self.encode_ref().write_encoded(mode, target)
1218    }
1219}
1220
1221/// Other certificate format.
1222///
1223/// ```ASN.1
1224/// OtherCertificateFormat ::= SEQUENCE {
1225///   otherCertFormat OBJECT IDENTIFIER,
1226///   otherCert ANY DEFINED BY otherCertFormat }
1227/// ```
1228#[derive(Clone, Debug, Eq, PartialEq)]
1229pub struct OtherCertificateFormat {
1230    pub other_cert_format: Oid,
1231    // TODO Any
1232    pub other_cert: Option<()>,
1233}
1234
1235impl OtherCertificateFormat {
1236    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
1237        Err(cons.content_err("OtherCertificateFormat parsing not implemented"))
1238    }
1239}
1240
1241#[derive(Clone, Debug, Default, Eq, PartialEq)]
1242pub struct CertificateSet(Vec<CertificateChoices>);
1243
1244impl Deref for CertificateSet {
1245    type Target = Vec<CertificateChoices>;
1246
1247    fn deref(&self) -> &Self::Target {
1248        &self.0
1249    }
1250}
1251
1252impl DerefMut for CertificateSet {
1253    fn deref_mut(&mut self) -> &mut Self::Target {
1254        &mut self.0
1255    }
1256}
1257
1258impl CertificateSet {
1259    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
1260        let mut certs = Vec::new();
1261
1262        while let Some(cert) = CertificateChoices::take_opt_from(cons)? {
1263            certs.push(cert);
1264        }
1265
1266        Ok(Self(certs))
1267    }
1268
1269    pub fn encode_ref_as(&self, tag: Tag) -> impl Values + '_ {
1270        encode::set_as(tag, &self.0)
1271    }
1272}
1273
1274/// Issuer and serial number.
1275///
1276/// ```ASN.1
1277/// IssuerAndSerialNumber ::= SEQUENCE {
1278///   issuer Name,
1279///   serialNumber CertificateSerialNumber }
1280/// ```
1281#[derive(Clone, Debug, Eq, PartialEq)]
1282pub struct IssuerAndSerialNumber {
1283    pub issuer: Name,
1284    pub serial_number: CertificateSerialNumber,
1285}
1286
1287impl IssuerAndSerialNumber {
1288    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
1289        cons.take_sequence(|cons| {
1290            let issuer = Name::take_from(cons)?;
1291            let serial_number = Integer::take_from(cons)?;
1292
1293            Ok(Self {
1294                issuer,
1295                serial_number,
1296            })
1297        })
1298    }
1299
1300    pub fn encode_ref(&self) -> impl Values + '_ {
1301        encode::sequence((self.issuer.encode_ref(), (&self.serial_number).encode()))
1302    }
1303}
1304
1305pub type CertificateSerialNumber = Integer;
1306
1307/// Version number.
1308///
1309/// ```ASN.1
1310/// CMSVersion ::= INTEGER
1311///                { v0(0), v1(1), v2(2), v3(3), v4(4), v5(5) }
1312/// ```
1313#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1314pub enum CmsVersion {
1315    V0 = 0,
1316    V1 = 1,
1317    V2 = 2,
1318    V3 = 3,
1319    V4 = 4,
1320    V5 = 5,
1321}
1322
1323impl CmsVersion {
1324    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
1325        match cons.take_primitive_if(Tag::INTEGER, Integer::i8_from_primitive)? {
1326            0 => Ok(Self::V0),
1327            1 => Ok(Self::V1),
1328            2 => Ok(Self::V2),
1329            3 => Ok(Self::V3),
1330            4 => Ok(Self::V4),
1331            5 => Ok(Self::V5),
1332            _ => Err(cons.content_err("unexpected CMSVersion")),
1333        }
1334    }
1335
1336    pub fn encode(self) -> impl Values {
1337        u8::from(self).encode()
1338    }
1339}
1340
1341impl From<CmsVersion> for u8 {
1342    fn from(v: CmsVersion) -> u8 {
1343        match v {
1344            CmsVersion::V0 => 0,
1345            CmsVersion::V1 => 1,
1346            CmsVersion::V2 => 2,
1347            CmsVersion::V3 => 3,
1348            CmsVersion::V4 => 4,
1349            CmsVersion::V5 => 5,
1350        }
1351    }
1352}
1353
1354pub type UserKeyingMaterial = OctetString;
1355
1356/// Other key attribute.
1357///
1358/// ```ASN.1
1359/// OtherKeyAttribute ::= SEQUENCE {
1360///   keyAttrId OBJECT IDENTIFIER,
1361///   keyAttr ANY DEFINED BY keyAttrId OPTIONAL }
1362/// ```
1363#[derive(Clone, Debug, Eq, PartialEq)]
1364pub struct OtherKeyAttribute {
1365    pub key_attribute_id: Oid,
1366    // TODO Any
1367    pub key_attribute: Option<()>,
1368}
1369
1370pub type ContentType = Oid;
1371
1372pub type MessageDigest = OctetString;
1373
1374pub type SigningTime = Time;
1375
1376/// Time variant.
1377///
1378/// ```ASN.1
1379/// Time ::= CHOICE {
1380///   utcTime UTCTime,
1381///   generalizedTime GeneralizedTime }
1382/// ```
1383#[derive(Clone, Debug, Eq, PartialEq)]
1384pub enum Time {
1385    UtcTime(UtcTime),
1386    GeneralizedTime(GeneralizedTime),
1387}
1388
1389impl Time {
1390    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
1391        if let Some(utc) =
1392            cons.take_opt_primitive_if(Tag::UTC_TIME, |prim| UtcTime::from_primitive(prim))?
1393        {
1394            Ok(Self::UtcTime(utc))
1395        } else if let Some(generalized) = cons
1396            .take_opt_primitive_if(Tag::GENERALIZED_TIME, |prim| {
1397                GeneralizedTime::from_primitive_no_fractional_or_timezone_offsets(prim)
1398            })?
1399        {
1400            Ok(Self::GeneralizedTime(generalized))
1401        } else {
1402            Err(cons.content_err("invalid Time value"))
1403        }
1404    }
1405}
1406
1407impl From<Time> for chrono::DateTime<chrono::Utc> {
1408    fn from(t: Time) -> Self {
1409        match t {
1410            Time::UtcTime(utc) => *utc,
1411            Time::GeneralizedTime(gt) => gt.into(),
1412        }
1413    }
1414}
1415
1416pub type CounterSignature = SignerInfo;
1417
1418pub type AttributeCertificateV2 = AttributeCertificate;