rasn_cms/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4extern crate alloc;
5
6pub mod algorithms;
7pub mod authenticode;
8pub mod firmware_wrapper;
9pub mod pkcs7_compat;
10
11use alloc::boxed::Box;
12
13use rasn::prelude::*;
14pub use rasn_pkix::{
15    AlgorithmIdentifier, Attribute, Certificate, CertificateList, CertificateSerialNumber, Name,
16    SubjectKeyIdentifier,
17};
18
19/// OID of top-level CMS ContentInfo
20pub const CONTENT_INFO: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS9_SMIME_CT_CONTENTINFO;
21
22/// OID of CMS ContentType
23pub const CONTENT_TYPE: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS9_CONTENT_TYPE;
24
25/// OID of MessageDigest
26pub const MESSAGE_DIGEST: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS9_MESSAGE_DIGEST;
27
28/// OID of SigningTime
29pub const SIGNING_TIME: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS9_SIGNING_TIME;
30
31/// OID of CounterSignature
32pub const COUNTER_SIGNATURE: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS9_COUNTER_SIGNATURE;
33
34// content types
35/// OID of Data content type
36pub const CONTENT_DATA: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS7_DATA;
37
38/// OID of SignedData content type
39pub const CONTENT_SIGNED_DATA: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS7_SIGNED_DATA;
40
41/// OID of EnvelopedData content type
42pub const CONTENT_ENVELOPED_DATA: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS7_ENVELOPED_DATA;
43
44/// OID of DigestedData content type
45pub const CONTENT_DIGESTED_DATA: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS7_DIGESTED_DATA;
46
47/// OID of EncryptedData content type
48pub const CONTENT_ENCRYPTED_DATA: &Oid = Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS7_ENCRYPTED_DATA;
49
50/// OID of AuthenticatedData content type
51pub const CONTENT_AUTHENTICATED_DATA: &Oid =
52    Oid::ISO_MEMBER_BODY_US_RSADSI_PKCS9_SMIME_CT_AUTHENTICATED_DATA;
53
54pub type CmsVersion = Integer;
55pub type ContentType = ObjectIdentifier;
56pub type DigestAlgorithmIdentifier = AlgorithmIdentifier;
57pub type DigestAlgorithmIdentifiers = SetOf<DigestAlgorithmIdentifier>;
58pub type SignatureAlgorithmIdentifier = AlgorithmIdentifier;
59pub type ContentEncryptionAlgorithmIdentifier = AlgorithmIdentifier;
60pub type KeyEncryptionAlgorithmIdentifier = AlgorithmIdentifier;
61pub type KeyDerivationAlgorithmIdentifier = AlgorithmIdentifier;
62pub type MessageAuthenticationCodeAlgorithm = AlgorithmIdentifier;
63pub type CertificateSet = SetOf<CertificateChoices>;
64pub type RevocationInfoChoices = SetOf<RevocationInfoChoice>;
65pub type SignerInfos = SetOf<SignerInfo>;
66pub type SignedAttributes = SetOf<Attribute>;
67pub type UnsignedAttributes = SetOf<Attribute>;
68pub type SignatureValue = OctetString;
69pub type RecipientInfos = SetOf<RecipientInfo>;
70pub type UnprotectedAttributes = SetOf<Attribute>;
71pub type EncryptedContent = OctetString;
72pub type EncryptedKey = OctetString;
73pub type RecipientEncryptedKeys = SequenceOf<RecipientEncryptedKey>;
74pub type UserKeyingMaterial = OctetString;
75pub type Digest = OctetString;
76pub type AuthAttributes = SetOf<Attribute>;
77pub type UnauthAttributes = SetOf<Attribute>;
78pub type MessageAuthenticationCode = OctetString;
79pub type Signature = BitString;
80
81#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
82pub struct AuthEnvelopedData {
83    pub version: CmsVersion,
84    #[rasn(tag(0))]
85    pub originator_info: Option<OriginatorInfo>,
86    pub recipient_infos: RecipientInfos,
87    pub auth_encrypted_content_info: EncryptedContentInfo,
88    #[rasn(tag(1))]
89    pub auth_attrs: Option<AuthAttributes>,
90    pub mac: MessageAuthenticationCode,
91    #[rasn(tag(2))]
92    pub unauth_attrs: Option<UnauthAttributes>,
93}
94
95/// ContentInfo encapsulates a single identified content type, and the
96/// identified type may provide further encapsulation.
97#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
98pub struct ContentInfo {
99    pub content_type: ContentType,
100    #[rasn(tag(explicit(0)))]
101    pub content: Any,
102}
103
104/// SignedData represents a signed-data content type
105#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
106pub struct SignedData {
107    pub version: CmsVersion,
108    pub digest_algorithms: DigestAlgorithmIdentifiers,
109    pub encap_content_info: EncapsulatedContentInfo,
110    #[rasn(tag(0))]
111    pub certificates: Option<CertificateSet>,
112    #[rasn(tag(1))]
113    pub crls: Option<RevocationInfoChoices>,
114    pub signer_infos: SignerInfos,
115}
116
117/// EnvelopedData represents an enveloped-data content type
118#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
119pub struct EnvelopedData {
120    pub version: CmsVersion,
121    #[rasn(tag(0))]
122    pub originator_info: Option<OriginatorInfo>,
123    pub recipient_infos: RecipientInfos,
124    pub encrypted_content_info: EncryptedContentInfo,
125    #[rasn(tag(1))]
126    pub unprotected_attrs: Option<UnprotectedAttributes>,
127}
128
129/// DigestedData represents a digested-data content type
130#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
131pub struct DigestedData {
132    pub version: CmsVersion,
133    pub digest_algorithm: DigestAlgorithmIdentifier,
134    pub encap_content_info: EncapsulatedContentInfo,
135    pub digest: Digest,
136}
137
138/// EncryptedData represents an encrypted-data content type
139#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
140pub struct EncryptedData {
141    pub version: CmsVersion,
142    pub encrypted_content_info: EncryptedContentInfo,
143    #[rasn(tag(1))]
144    pub unprotected_attrs: Option<UnprotectedAttributes>,
145}
146
147/// AuthenticatedData represents an authenticated-data content type
148#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
149pub struct AuthenticatedData {
150    pub version: CmsVersion,
151    #[rasn(tag(0))]
152    pub originator_info: Option<OriginatorInfo>,
153    pub recipient_infos: RecipientInfos,
154    pub mac_algorithm: MessageAuthenticationCodeAlgorithm,
155    #[rasn(tag(1))]
156    pub digest_algorithm: Option<DigestAlgorithmIdentifier>,
157    pub encap_content_info: EncapsulatedContentInfo,
158    #[rasn(tag(2))]
159    pub auth_attrs: Option<AuthAttributes>,
160    pub mac: MessageAuthenticationCode,
161    #[rasn(tag(3))]
162    pub unauth_attrs: Option<UnauthAttributes>,
163}
164
165/// The `CertificateChoices`` type contains options for certificate formats.
166///
167/// It gives either a PKCS #6 extended
168/// certificate, an X.509 certificate, a version 1 X.509
169///  attribute certificate (ACv1) [X.509-97], a version 2 X.509 attribute
170/// certificate (ACv2) [X.509-00], or any other certificate format.
171#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
172#[rasn(choice)]
173pub enum CertificateChoices {
174    Certificate(Box<Certificate>),
175    #[rasn(tag(0))]
176    ExtendedCertificate(Box<ExtendedCertificate>),
177    #[rasn(tag(2))]
178    V2AttributeCertificate(Box<rasn_pkix::attribute_certificate::AttributeCertificate>),
179    #[rasn(tag(3))]
180    Other(OtherCertificateFormat),
181}
182
183/// OtherCertificateFormat represents a custom certificate format
184#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
185pub struct OtherCertificateFormat {
186    pub other_cert_format: ObjectIdentifier,
187    pub other_cert: Any,
188}
189
190/// The RevocationInfoChoice type gives a revocation status information alternatives.
191///
192/// It is intended that the set contain
193/// information sufficient to determine whether the certificates and
194/// attribute certificates with which the set is associated are revoked.
195#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
196#[rasn(choice)]
197pub enum RevocationInfoChoice {
198    Crl(CertificateList),
199    #[rasn(tag(1))]
200    Other(OtherRevocationInfoFormat),
201}
202
203/// The OtherRevocationInfoFormat alternative is provided to support any
204/// other revocation information format without further modifications to
205/// the CMS.
206#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
207pub struct OtherRevocationInfoFormat {
208    pub other_rev_info_format: ObjectIdentifier,
209    pub other_rev_info: Any,
210}
211
212/// The content is represented in the type EncapsulatedContentInfo
213#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
214pub struct EncapsulatedContentInfo {
215    pub content_type: ContentType,
216    #[rasn(tag(explicit(0)))]
217    pub content: Option<OctetString>,
218}
219
220/// Per-signer information is represented in the type SignerInfo
221#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
222pub struct SignerInfo {
223    pub version: CmsVersion,
224    pub sid: SignerIdentifier,
225    pub digest_algorithm: DigestAlgorithmIdentifier,
226    #[rasn(tag(0))]
227    pub signed_attrs: Option<SignedAttributes>,
228    pub signature_algorithm: SignatureAlgorithmIdentifier,
229    pub signature: SignatureValue,
230    #[rasn(tag(1))]
231    pub unsigned_attrs: Option<UnsignedAttributes>,
232}
233
234/// SignerIdentifier data type represents the choice of signer identifications
235#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
236#[rasn(choice)]
237pub enum SignerIdentifier {
238    IssuerAndSerialNumber(IssuerAndSerialNumber),
239    #[rasn(tag(0))]
240    SubjectKeyIdentifier(SubjectKeyIdentifier),
241}
242
243/// The IssuerAndSerialNumber type identifies a certificate, and thereby
244/// an entity and a public key, by the distinguished name of the
245/// certificate issuer and an issuer-specific certificate serial number.
246#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
247pub struct IssuerAndSerialNumber {
248    pub issuer: Name,
249    pub serial_number: CertificateSerialNumber,
250}
251
252/// OriginatorInfo optionally provides information about the
253/// originator. It is present only if required by the key management algorithm.
254#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
255pub struct OriginatorInfo {
256    #[rasn(tag(0))]
257    pub certs: Option<CertificateSet>,
258    #[rasn(tag(1))]
259    pub crls: Option<RevocationInfoChoices>,
260}
261
262/// EncryptedContentInfo is the encrypted content information
263#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
264pub struct EncryptedContentInfo {
265    pub content_type: ContentType,
266    pub content_encryption_algorithm: ContentEncryptionAlgorithmIdentifier,
267    #[rasn(tag(0))]
268    pub encrypted_content: Option<EncryptedContent>,
269}
270
271/// RecipientInfo is a per-recipient information.
272#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
273#[rasn(choice)]
274pub enum RecipientInfo {
275    KeyTransRecipientInfo(KeyTransRecipientInfo),
276    #[rasn(tag(1))]
277    KeyAgreeRecipientInfo(KeyAgreeRecipientInfo),
278    #[rasn(tag(2))]
279    KekRecipientInfo(KekRecipientInfo),
280    #[rasn(tag(3))]
281    PasswordRecipientInfo(PasswordRecipientInfo),
282    #[rasn(tag(4))]
283    OtherRecipientInfo(OtherRecipientInfo),
284}
285
286/// Per-recipient information using key transport is represented in the
287/// type KeyTransRecipientInfo.  Each instance of KeyTransRecipientInfo
288/// transfers the content-encryption key to one recipient.
289#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
290pub struct KeyTransRecipientInfo {
291    pub version: CmsVersion,
292    pub rid: RecipientIdentifier,
293    pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
294    pub encrypted_key: EncryptedKey,
295}
296
297/// RecipientIdentifier specifies the recipient's certificate or key that was used by
298/// the sender to protect the content-encryption key.
299#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
300#[rasn(choice)]
301pub enum RecipientIdentifier {
302    IssuerAndSerialNumber(IssuerAndSerialNumber),
303    #[rasn(tag(0))]
304    SubjectKeyIdentifier(SubjectKeyIdentifier),
305}
306
307/// Recipient information using key agreement is represented in the type
308/// KeyAgreeRecipientInfo.
309#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
310pub struct KeyAgreeRecipientInfo {
311    pub version: CmsVersion,
312    #[rasn(tag(explicit(0)))]
313    pub originator: OriginatorIdentifierOrKey,
314    #[rasn(tag(explicit(1)))]
315    pub user_keying_material: Option<UserKeyingMaterial>,
316    pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
317    pub recipient_encrypted_keys: RecipientEncryptedKeys,
318}
319
320/// RecipientEncryptedKey includes a recipient identifier and
321/// encrypted key for one or more recipients.
322#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
323pub struct RecipientEncryptedKey {
324    pub key_agree_recipient_identifier: KeyAgreeRecipientIdentifier,
325    pub encrypted_key: EncryptedKey,
326}
327
328/// KeyAgreeRecipientIdentifier is a CHOICE with two alternatives.
329///
330/// Alternatives specify the recipient's certificate, and thereby the
331/// recipient's public key, that was used by the sender to generate a
332/// pairwise key-encryption key.
333#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
334#[rasn(choice)]
335pub enum KeyAgreeRecipientIdentifier {
336    IssuerAndSerialNumber(IssuerAndSerialNumber),
337    #[rasn(tag(0))]
338    RecipientKeyIdentifier(RecipientKeyIdentifier),
339}
340
341/// RecipientKeyIdentifier identifies the recipient's key.
342#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
343pub struct RecipientKeyIdentifier {
344    pub subject_key_identifier: SubjectKeyIdentifier,
345    pub date: Option<GeneralizedTime>,
346    pub other: Option<OtherKeyAttribute>,
347}
348
349/// Additional information used by the recipient to determine
350/// the key-encryption key used by the sender.
351#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
352pub struct OtherKeyAttribute {
353    pub key_attr_id: ObjectIdentifier,
354    pub key_attr: Option<Any>,
355}
356
357/// OriginatorIdentifierOrKey is a CHOICE with three alternatives specifying the
358/// sender's key agreement public key.
359#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
360#[rasn(choice)]
361pub enum OriginatorIdentifierOrKey {
362    IssuerAndSerialNumber(IssuerAndSerialNumber),
363    #[rasn(tag(0))]
364    SubjectKeyIdentifier(SubjectKeyIdentifier),
365    #[rasn(tag(1))]
366    OriginatorPublicKey(OriginatorPublicKey),
367}
368
369/// The OriginatorPublicKey alternative
370/// includes the algorithm identifier and sender's key agreement
371/// public key.
372#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
373pub struct OriginatorPublicKey {
374    pub algorithm: AlgorithmIdentifier,
375    pub public_key: BitString,
376}
377
378/// Recipient information using previously distributed symmetric keys is
379/// represented in the type KEKRecipientInfo.
380#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
381pub struct KekRecipientInfo {
382    pub version: CmsVersion,
383    pub kek_id: KekIdentifier,
384    pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
385    pub encrypted_key: EncryptedKey,
386}
387
388/// KekIdentifier specifies a symmetric key-encryption key that was previously
389/// distributed to the sender and one or more recipients.
390#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
391pub struct KekIdentifier {
392    pub key_identifier: OctetString,
393    pub date: Option<GeneralizedTime>,
394    pub other: Option<OtherKeyAttribute>,
395}
396
397/// Recipient information using a password or shared secret value is
398/// represented in the type PasswordRecipientInfo.
399#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
400pub struct PasswordRecipientInfo {
401    pub version: CmsVersion,
402    #[rasn(tag(0))]
403    pub key_derivation_algorithm: Option<KeyDerivationAlgorithmIdentifier>,
404    pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier,
405    pub encrypted_eey: EncryptedKey,
406}
407
408/// Recipient information for additional key management techniques are
409/// represented in the type OtherRecipientInfo.
410#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
411pub struct OtherRecipientInfo {
412    pub ori_type: ObjectIdentifier,
413    pub ori_value: Any,
414}
415
416#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
417#[rasn(choice)]
418pub enum ExtendedCertificateOrCertificate {
419    Certificate(Certificate),
420    #[rasn(tag(0))]
421    ExtendedCertificate(ExtendedCertificate),
422}
423
424#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
425pub struct ExtendedCertificate {
426    pub extended_certificate_info: ExtendedCertificateInfo,
427    pub signature_algorithm: SignatureAlgorithmIdentifier,
428    pub signature: Signature,
429}
430
431#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
432pub struct ExtendedCertificateInfo {
433    pub version: CmsVersion,
434    pub certificate: Certificate,
435    pub attributes: UnauthAttributes,
436}