quantcrypt/cms/asn1/
auth_enveloped_data_builder.rs1use crate::cea::common::cea_trait::Cea;
5use cms::authenticated_data::MessageAuthenticationCode;
6use cms::builder::Error;
7use cms::content_info::CmsVersion;
8use cms::enveloped_data::{EncryptedContentInfo, RecipientInfo, RecipientInfos};
9use cms::{builder::RecipientInfoBuilder, enveloped_data::OriginatorInfo};
10use const_oid::db::rfc5911::{ID_AES_128_GCM, ID_AES_192_GCM, ID_AES_256_GCM};
11use der::{Decode, Encode};
12use spki::ObjectIdentifier;
13use x509_cert::attr::Attributes;
14use zeroize::Zeroize;
15
16use crate::cea::cea_manager::CeaManager;
17use crate::cea::common::cea_type::CeaType;
18use crate::QuantCryptError;
19
20use crate::cms::asn1::auth_env_data::AuthEnvelopedData;
21
22type Result<T> = std::result::Result<T, QuantCryptError>;
23
24#[derive(Clone, Debug, Eq, PartialEq)]
26pub enum ContentEncryptionAlgorithmAead {
27 Aes128Gcm,
29 Aes192Gcm,
31 Aes256Gcm,
33}
34
35pub struct AuthEnvelopedDataBuilder<'c> {
37 content_id: Option<ObjectIdentifier>,
38 originator_info: Option<OriginatorInfo>,
39 recipient_infos: Vec<Box<dyn RecipientInfoBuilder + 'c>>,
40 unencrypted_content: &'c [u8],
41 content_encryption_algorithm: ContentEncryptionAlgorithmAead,
51 auth_attributes: Option<Attributes>,
52 unauth_attributes: Option<Attributes>,
53}
54
55impl ContentEncryptionAlgorithmAead {
56 pub fn oid(&self) -> ObjectIdentifier {
58 match self {
59 ContentEncryptionAlgorithmAead::Aes128Gcm => ID_AES_128_GCM,
60 ContentEncryptionAlgorithmAead::Aes192Gcm => ID_AES_192_GCM,
61 ContentEncryptionAlgorithmAead::Aes256Gcm => ID_AES_256_GCM,
62 }
63 }
64}
65
66impl<'c> AuthEnvelopedDataBuilder<'c> {
67 pub fn new(
69 content_id: Option<ObjectIdentifier>,
70 originator_info: Option<OriginatorInfo>,
71 unencrypted_content: &'c [u8],
72 content_encryption_algorithm: ContentEncryptionAlgorithmAead,
73 auth_attributes: Option<Attributes>,
74 unauth_attributes: Option<Attributes>,
75 ) -> Result<AuthEnvelopedDataBuilder<'c>> {
76 Ok(AuthEnvelopedDataBuilder {
77 content_id,
78 originator_info,
79 recipient_infos: Vec::new(),
80 unencrypted_content,
81 content_encryption_algorithm,
82 auth_attributes,
83 unauth_attributes,
84 })
85 }
86
87 pub fn add_recipient_info(
90 &mut self,
91 recipient_info_builder: impl RecipientInfoBuilder + 'c,
92 ) -> Result<&mut Self> {
93 self.recipient_infos.push(Box::new(recipient_info_builder));
94 Ok(self)
95 }
96
97 pub fn build(&mut self) -> Result<AuthEnvelopedData> {
100 let aad = match &self.auth_attributes {
106 Some(attrs) => Some(attrs.to_der().map_err(|_| QuantCryptError::Unknown)?),
107 None => None,
108 };
109
110 let oid = self.content_encryption_algorithm.oid().to_string();
111 let cea_type = if let Some(oid) = CeaType::from_oid(&oid) {
112 oid
113 } else {
114 return Err(QuantCryptError::Unknown);
115 };
116
117 let mut cea = CeaManager::new(cea_type)?;
119 let mut cek = cea.key_gen()?;
121 let nonce = cea.nonce_gen()?;
122
123 let content_id = self.content_id.map(|oid| oid.to_string());
125
126 let (tag, eci) = cea.encrypt(
127 &cek,
128 Some(&nonce),
129 self.unencrypted_content,
130 aad.as_deref(),
131 content_id.as_deref(),
132 )?;
133
134 type Result<T> = core::result::Result<T, Error>;
135
136 let recipient_infos_vec = self
137 .recipient_infos
138 .iter_mut()
139 .map(|ri| ri.build(&cek))
140 .collect::<Result<Vec<RecipientInfo>>>()
141 .map_err(|_| QuantCryptError::Unknown)?;
142
143 cek.zeroize();
144 let recip_infos =
145 RecipientInfos::try_from(recipient_infos_vec).map_err(|_| QuantCryptError::Unknown)?;
146
147 let mac = MessageAuthenticationCode::new(tag).map_err(|_| QuantCryptError::Unknown)?;
148
149 let eci = EncryptedContentInfo::from_der(&eci).map_err(|_| QuantCryptError::Unknown)?;
150
151 Ok(AuthEnvelopedData {
152 version: self.calculate_version(),
153 originator_info: self.originator_info.clone(),
154 recip_infos,
155 auth_encrypted_content: eci,
156 auth_attrs: self.auth_attributes.clone(),
157 mac,
158 unauth_attrs: self.unauth_attributes.clone(),
159 })
160 }
161
162 fn calculate_version(&self) -> CmsVersion {
164 CmsVersion::V0
165 }
166}