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;