cms/
signed_data.rs

1//! SignedData-related types
2
3use crate::cert::{CertificateChoices, IssuerAndSerialNumber};
4use crate::content_info::CmsVersion;
5use crate::revocation::RevocationInfoChoices;
6
7use core::cmp::Ordering;
8use der::asn1::{ObjectIdentifier, OctetString, SetOfVec};
9use der::{Any, Choice, DerOrd, Sequence, ValueOrd};
10use spki::AlgorithmIdentifierOwned;
11use x509_cert::attr::Attributes;
12use x509_cert::ext::pkix::SubjectKeyIdentifier;
13use x509_cert::impl_newtype;
14
15/// The `SignedData` type is defined in [RFC 5652 Section 5.1].
16///
17/// ```text
18///   SignedData ::= SEQUENCE {
19///       version CMSVersion,
20///       digestAlgorithms SET OF DigestAlgorithmIdentifier,
21///       encapContentInfo EncapsulatedContentInfo,
22///       certificates [0] IMPLICIT CertificateSet OPTIONAL,
23///       crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
24///       signerInfos SignerInfos }
25/// ```
26///
27/// [RFC 5652 Section 5.1]: https://www.rfc-editor.org/rfc/rfc5652#section-5.1
28#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
29#[allow(missing_docs)]
30pub struct SignedData {
31    pub version: CmsVersion,
32    pub digest_algorithms: DigestAlgorithmIdentifiers,
33    pub encap_content_info: EncapsulatedContentInfo,
34    //todo consider defer decoding certs and CRLs
35    #[asn1(context_specific = "0", tag_mode = "IMPLICIT", optional = "true")]
36    pub certificates: Option<CertificateSet>,
37    #[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")]
38    pub crls: Option<RevocationInfoChoices>,
39    pub signer_infos: SignerInfos,
40}
41
42/// The `DigestAlgorithmIdentifiers` type is defined in [RFC 5652 Section 5.1].
43///
44/// ```text
45/// DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
46/// ```
47///
48/// [RFC 5652 Section 5.1]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.1
49pub type DigestAlgorithmIdentifiers = SetOfVec<AlgorithmIdentifierOwned>;
50
51/// CertificateSet structure as defined in [RFC 5652 Section 10.2.3].
52///
53/// ```text
54///   CertificateSet ::= SET OF CertificateChoices
55/// ```
56///
57/// [RFC 5652 Section 10.2.3]: https://datatracker.ietf.org/doc/html/rfc5652#section-10.2.3
58#[derive(Clone, Eq, PartialEq, Debug)]
59pub struct CertificateSet(pub SetOfVec<CertificateChoices>);
60impl_newtype!(CertificateSet, SetOfVec<CertificateChoices>);
61
62#[cfg(feature = "std")]
63impl TryFrom<std::vec::Vec<CertificateChoices>> for CertificateSet {
64    type Error = der::Error;
65
66    fn try_from(vec: std::vec::Vec<CertificateChoices>) -> der::Result<CertificateSet> {
67        Ok(CertificateSet(SetOfVec::try_from(vec)?))
68    }
69}
70
71/// The `SignerInfos` type is defined in [RFC 5652 Section 5.1].
72///
73/// ```text
74///   SignerInfos ::= SET OF SignerInfo
75/// ```
76///
77/// [RFC 5652 Section 5.1]: https://www.rfc-editor.org/rfc/rfc5652#section-5.1
78#[derive(Clone, Eq, PartialEq, Debug)]
79pub struct SignerInfos(pub SetOfVec<SignerInfo>);
80impl_newtype!(SignerInfos, SetOfVec<SignerInfo>);
81
82#[cfg(feature = "std")]
83impl TryFrom<std::vec::Vec<SignerInfo>> for SignerInfos {
84    type Error = der::Error;
85
86    fn try_from(vec: std::vec::Vec<SignerInfo>) -> der::Result<SignerInfos> {
87        Ok(SignerInfos(SetOfVec::try_from(vec)?))
88    }
89}
90
91/// The `EncapsulatedContentInfo` type is defined in [RFC 5652 Section 5.2].
92///
93/// ```text
94///   EncapsulatedContentInfo ::= SEQUENCE {
95///       eContentType       CONTENT-TYPE.&id({ContentSet}),
96///       eContent           [0] EXPLICIT OCTET STRING
97///               ( CONTAINING CONTENT-TYPE.
98///                   &Type({ContentSet}{@eContentType})) OPTIONAL }
99/// ```
100///
101/// [RFC 5652 Section 5.2]: https://www.rfc-editor.org/rfc/rfc5652#section-5.2
102#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
103#[allow(missing_docs)]
104pub struct EncapsulatedContentInfo {
105    pub econtent_type: ObjectIdentifier,
106    #[asn1(context_specific = "0", tag_mode = "EXPLICIT", optional = "true")]
107    pub econtent: Option<Any>,
108}
109
110/// The `SignerInfo` type is defined in [RFC 5652 Section 5.3].
111///
112/// ```text
113///   SignerInfo ::= SEQUENCE {
114///       version CMSVersion,
115///       sid SignerIdentifier,
116///       digestAlgorithm DigestAlgorithmIdentifier,
117///       signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
118///       signatureAlgorithm SignatureAlgorithmIdentifier,
119///       signature SignatureValue,
120///       unsignedAttrs [1] IMPLICIT Attributes
121///           {{UnsignedAttributes}} OPTIONAL }
122/// ```
123///
124/// [RFC 5652 Section 5.3]: https://www.rfc-editor.org/rfc/rfc5652#section-5.3
125#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
126#[allow(missing_docs)]
127pub struct SignerInfo {
128    pub version: CmsVersion,
129    pub sid: SignerIdentifier,
130    pub digest_alg: AlgorithmIdentifierOwned,
131    #[asn1(
132        context_specific = "0",
133        tag_mode = "IMPLICIT",
134        constructed = "true",
135        optional = "true"
136    )]
137    pub signed_attrs: Option<SignedAttributes>,
138    pub signature_algorithm: AlgorithmIdentifierOwned,
139    pub signature: SignatureValue,
140    #[asn1(
141        context_specific = "1",
142        tag_mode = "IMPLICIT",
143        constructed = "true",
144        optional = "true"
145    )]
146    pub unsigned_attrs: Option<UnsignedAttributes>,
147}
148
149/// The `SignerInfo` type is defined in [RFC 5652 Section 5.3].
150///
151/// ```text
152/// SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
153/// ```
154///
155/// [RFC 5652 Section 5.3]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
156pub type SignedAttributes = Attributes;
157
158/// The `SignerIdentifier` type is defined in [RFC 5652 Section 5.3].
159///
160/// ```text
161/// SignerIdentifier ::= CHOICE {
162///   issuerAndSerialNumber IssuerAndSerialNumber,
163///   subjectKeyIdentifier \[0\] SubjectKeyIdentifier }
164/// ```
165///
166/// [RFC 5652 Section 5.3]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
167#[derive(Clone, Debug, Eq, PartialEq, Choice)]
168#[allow(missing_docs)]
169pub enum SignerIdentifier {
170    IssuerAndSerialNumber(IssuerAndSerialNumber),
171
172    #[asn1(context_specific = "0", tag_mode = "IMPLICIT")]
173    SubjectKeyIdentifier(SubjectKeyIdentifier),
174}
175
176// TODO DEFER ValueOrd is not supported for CHOICE types (see new_enum in value_ord.rs)
177impl ValueOrd for SignerIdentifier {
178    fn value_cmp(&self, other: &Self) -> der::Result<Ordering> {
179        use der::Encode;
180        self.to_der()?.der_cmp(&other.to_der()?)
181    }
182}
183
184/// The `UnsignedAttributes` type is defined in [RFC 5652 Section 5.3].
185///
186/// ```text
187/// UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute
188/// ```
189///
190/// [RFC 5652 Section 5.3]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
191pub type UnsignedAttributes = Attributes;
192
193/// The `SignatureValue` type is defined in [RFC 5652 Section 5.3].
194///
195/// ```text
196///   SignatureValue ::= OCTET STRING
197/// ```
198///
199/// [RFC 5652 Section 5.3]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
200pub type SignatureValue = OctetString;