1use crate::encryption::{CryptFilterManager, EncryptionKey};
7use crate::error::Result;
8use crate::objects::{Dictionary, Object, ObjectId};
9use std::sync::Arc;
10
11pub struct EmbeddedFileEncryption {
13 eff_filter: Option<String>,
15 encrypt_metadata: bool,
17 filter_manager: Arc<CryptFilterManager>,
19}
20
21impl EmbeddedFileEncryption {
22 pub fn new(
24 eff_filter: Option<String>,
25 encrypt_metadata: bool,
26 filter_manager: Arc<CryptFilterManager>,
27 ) -> Self {
28 Self {
29 eff_filter,
30 encrypt_metadata,
31 filter_manager,
32 }
33 }
34
35 pub fn is_embedded_file(stream_dict: &Dictionary) -> bool {
37 if let Some(Object::Name(type_name)) = stream_dict.get("Type") {
38 type_name == "EmbeddedFile"
39 } else {
40 false
41 }
42 }
43
44 pub fn is_metadata(stream_dict: &Dictionary) -> bool {
46 if let Some(Object::Name(type_name)) = stream_dict.get("Type") {
47 type_name == "Metadata"
48 } else if let Some(Object::Name(subtype)) = stream_dict.get("Subtype") {
49 subtype == "XML" && stream_dict.contains_key("Metadata")
50 } else {
51 false
52 }
53 }
54
55 pub fn get_stream_filter(&self, stream_dict: &Dictionary) -> Option<String> {
57 if Self::is_embedded_file(stream_dict) {
58 self.eff_filter.clone()
60 } else if Self::is_metadata(stream_dict) && !self.encrypt_metadata {
61 Some("Identity".to_string())
63 } else {
64 None
66 }
67 }
68
69 pub fn encrypt_embedded_file(
71 &self,
72 data: &[u8],
73 obj_id: &ObjectId,
74 encryption_key: &EncryptionKey,
75 ) -> Result<Vec<u8>> {
76 if let Some(ref _filter_name) = self.eff_filter {
77 self.filter_manager.encrypt_stream(
78 data,
79 obj_id,
80 &Dictionary::new(), encryption_key,
82 )
83 } else {
84 Ok(data.to_vec())
86 }
87 }
88
89 pub fn decrypt_embedded_file(
91 &self,
92 data: &[u8],
93 obj_id: &ObjectId,
94 encryption_key: &EncryptionKey,
95 ) -> Result<Vec<u8>> {
96 if let Some(ref _filter_name) = self.eff_filter {
97 self.filter_manager.decrypt_stream(
98 data,
99 obj_id,
100 &Dictionary::new(), encryption_key,
102 )
103 } else {
104 Ok(data.to_vec())
106 }
107 }
108
109 pub fn process_stream_encryption(
111 &self,
112 stream_dict: &Dictionary,
113 data: &[u8],
114 obj_id: &ObjectId,
115 encryption_key: &EncryptionKey,
116 encrypt: bool,
117 ) -> Result<Vec<u8>> {
118 if Self::is_embedded_file(stream_dict) {
120 if encrypt {
121 self.encrypt_embedded_file(data, obj_id, encryption_key)
122 } else {
123 self.decrypt_embedded_file(data, obj_id, encryption_key)
124 }
125 } else if Self::is_metadata(stream_dict) && !self.encrypt_metadata {
126 Ok(data.to_vec())
128 } else {
129 if encrypt {
131 self.filter_manager
132 .encrypt_stream(data, obj_id, stream_dict, encryption_key)
133 } else {
134 self.filter_manager
135 .decrypt_stream(data, obj_id, stream_dict, encryption_key)
136 }
137 }
138 }
139}
140
141pub struct ExtendedEncryptionDict {
143 pub base: crate::encryption::EncryptionDictionary,
145 pub eff: Option<String>,
147}
148
149impl ExtendedEncryptionDict {
150 pub fn new(base: crate::encryption::EncryptionDictionary, eff: Option<String>) -> Self {
152 Self { base, eff }
153 }
154
155 pub fn to_dict(&self) -> Dictionary {
157 let mut dict = self.base.to_dict();
158
159 if let Some(ref eff) = self.eff {
161 dict.set("EFF", Object::Name(eff.clone()));
162 }
163
164 dict
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171 use crate::encryption::{
172 AuthEvent, CryptFilterMethod, FunctionalCryptFilter, StandardSecurityHandler,
173 };
174
175 fn create_test_filter_manager() -> Arc<CryptFilterManager> {
176 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
177 let mut manager =
178 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
179
180 manager.add_filter(FunctionalCryptFilter {
182 name: "StdCF".to_string(),
183 method: CryptFilterMethod::V2,
184 length: Some(16),
185 auth_event: AuthEvent::DocOpen,
186 recipients: None,
187 });
188
189 manager.add_filter(FunctionalCryptFilter {
191 name: "EmbeddedFileFilter".to_string(),
192 method: CryptFilterMethod::AESV2,
193 length: None,
194 auth_event: AuthEvent::EFOpen,
195 recipients: None,
196 });
197
198 Arc::new(manager)
199 }
200
201 #[test]
202 fn test_is_embedded_file() {
203 let mut dict = Dictionary::new();
204 assert!(!EmbeddedFileEncryption::is_embedded_file(&dict));
205
206 dict.set("Type", Object::Name("EmbeddedFile".to_string()));
207 assert!(EmbeddedFileEncryption::is_embedded_file(&dict));
208
209 dict.set("Type", Object::Name("Stream".to_string()));
210 assert!(!EmbeddedFileEncryption::is_embedded_file(&dict));
211 }
212
213 #[test]
214 fn test_is_metadata() {
215 let mut dict = Dictionary::new();
216 assert!(!EmbeddedFileEncryption::is_metadata(&dict));
217
218 dict.set("Type", Object::Name("Metadata".to_string()));
220 assert!(EmbeddedFileEncryption::is_metadata(&dict));
221
222 let mut dict2 = Dictionary::new();
224 dict2.set("Subtype", Object::Name("XML".to_string()));
225 dict2.set("Metadata", Object::Null);
226 assert!(EmbeddedFileEncryption::is_metadata(&dict2));
227 }
228
229 #[test]
230 fn test_get_stream_filter() {
231 let filter_manager = create_test_filter_manager();
232 let handler = EmbeddedFileEncryption::new(
233 Some("EmbeddedFileFilter".to_string()),
234 false,
235 filter_manager,
236 );
237
238 let mut ef_dict = Dictionary::new();
240 ef_dict.set("Type", Object::Name("EmbeddedFile".to_string()));
241 assert_eq!(
242 handler.get_stream_filter(&ef_dict),
243 Some("EmbeddedFileFilter".to_string())
244 );
245
246 let mut meta_dict = Dictionary::new();
248 meta_dict.set("Type", Object::Name("Metadata".to_string()));
249 assert_eq!(
250 handler.get_stream_filter(&meta_dict),
251 Some("Identity".to_string())
252 );
253
254 let regular_dict = Dictionary::new();
256 assert_eq!(handler.get_stream_filter(®ular_dict), None);
257 }
258
259 #[test]
260 fn test_get_stream_filter_with_metadata_encryption() {
261 let filter_manager = create_test_filter_manager();
262 let handler = EmbeddedFileEncryption::new(
263 Some("EmbeddedFileFilter".to_string()),
264 true, filter_manager,
266 );
267
268 let mut meta_dict = Dictionary::new();
270 meta_dict.set("Type", Object::Name("Metadata".to_string()));
271 assert_eq!(handler.get_stream_filter(&meta_dict), None); }
273
274 #[test]
275 fn test_encrypt_embedded_file() {
276 let filter_manager = create_test_filter_manager();
277 let handler = EmbeddedFileEncryption::new(
278 Some("EmbeddedFileFilter".to_string()),
279 false,
280 filter_manager,
281 );
282
283 let data = b"Embedded file content";
284 let obj_id = ObjectId::new(1, 0);
285 let key = EncryptionKey::new(vec![0x01; 16]);
286
287 let encrypted = handler.encrypt_embedded_file(data, &obj_id, &key).unwrap();
288 assert_ne!(encrypted, data);
289 }
290
291 #[test]
292 fn test_encrypt_embedded_file_no_eff() {
293 let filter_manager = create_test_filter_manager();
294 let handler = EmbeddedFileEncryption::new(
295 None, false,
297 filter_manager,
298 );
299
300 let data = b"Embedded file content";
301 let obj_id = ObjectId::new(1, 0);
302 let key = EncryptionKey::new(vec![0x01; 16]);
303
304 let result = handler.encrypt_embedded_file(data, &obj_id, &key).unwrap();
305 assert_eq!(result, data); }
307
308 #[test]
309 fn test_process_stream_encryption_embedded_file() {
310 let filter_manager = create_test_filter_manager();
311 let handler = EmbeddedFileEncryption::new(
312 Some("EmbeddedFileFilter".to_string()),
313 false,
314 filter_manager,
315 );
316
317 let mut dict = Dictionary::new();
318 dict.set("Type", Object::Name("EmbeddedFile".to_string()));
319
320 let data = b"Embedded file data";
321 let obj_id = ObjectId::new(1, 0);
322 let key = EncryptionKey::new(vec![0x01; 16]);
323
324 let encrypted = handler
325 .process_stream_encryption(
326 &dict, data, &obj_id, &key, true, )
328 .unwrap();
329
330 assert_ne!(encrypted, data);
331 }
332
333 #[test]
334 fn test_process_stream_encryption_metadata_no_encrypt() {
335 let filter_manager = create_test_filter_manager();
336 let handler = EmbeddedFileEncryption::new(
337 Some("EmbeddedFileFilter".to_string()),
338 false, filter_manager,
340 );
341
342 let mut dict = Dictionary::new();
343 dict.set("Type", Object::Name("Metadata".to_string()));
344
345 let data = b"Metadata content";
346 let obj_id = ObjectId::new(1, 0);
347 let key = EncryptionKey::new(vec![0x01; 16]);
348
349 let result = handler
350 .process_stream_encryption(
351 &dict, data, &obj_id, &key, true, )
353 .unwrap();
354
355 assert_eq!(result, data); }
357
358 #[test]
359 fn test_process_stream_encryption_regular_stream() {
360 let filter_manager = create_test_filter_manager();
361 let handler = EmbeddedFileEncryption::new(
362 Some("EmbeddedFileFilter".to_string()),
363 true,
364 filter_manager,
365 );
366
367 let dict = Dictionary::new(); let data = b"Regular stream data";
369 let obj_id = ObjectId::new(1, 0);
370 let key = EncryptionKey::new(vec![0x01; 16]);
371
372 let encrypted = handler
373 .process_stream_encryption(
374 &dict, data, &obj_id, &key, true, )
376 .unwrap();
377
378 assert_ne!(encrypted, data); }
380
381 #[test]
382 fn test_extended_encryption_dict() {
383 let base = crate::encryption::EncryptionDictionary::rc4_128bit(
384 vec![0u8; 32],
385 vec![1u8; 32],
386 crate::encryption::Permissions::all(),
387 None,
388 );
389
390 let extended = ExtendedEncryptionDict::new(base, Some("EmbeddedFileFilter".to_string()));
391
392 let dict = extended.to_dict();
393 assert_eq!(
394 dict.get("EFF"),
395 Some(&Object::Name("EmbeddedFileFilter".to_string()))
396 );
397 }
398
399 #[test]
400 fn test_extended_encryption_dict_no_eff() {
401 let base = crate::encryption::EncryptionDictionary::rc4_128bit(
402 vec![0u8; 32],
403 vec![1u8; 32],
404 crate::encryption::Permissions::all(),
405 None,
406 );
407
408 let extended = ExtendedEncryptionDict::new(base, None);
409 let dict = extended.to_dict();
410
411 assert!(!dict.contains_key("EFF"));
412 }
413
414 #[test]
415 fn test_decrypt_embedded_file() {
416 let filter_manager = create_test_filter_manager();
417 let handler = EmbeddedFileEncryption::new(
418 Some("EmbeddedFileFilter".to_string()),
419 false,
420 filter_manager,
421 );
422
423 let data = b"Encrypted embedded file";
424 let obj_id = ObjectId::new(1, 0);
425 let key = EncryptionKey::new(vec![0x01; 16]);
426
427 let encrypted = handler.encrypt_embedded_file(data, &obj_id, &key).unwrap();
429
430 let decrypted = handler
432 .decrypt_embedded_file(&encrypted, &obj_id, &key)
433 .unwrap();
434
435 assert_eq!(decrypted, data);
437 }
438
439 #[test]
440 fn test_process_stream_decryption() {
441 let filter_manager = create_test_filter_manager();
442 let handler = EmbeddedFileEncryption::new(
443 Some("EmbeddedFileFilter".to_string()),
444 false,
445 filter_manager,
446 );
447
448 let mut dict = Dictionary::new();
449 dict.set("Type", Object::Name("EmbeddedFile".to_string()));
450
451 let original_data = b"Original embedded file";
452 let obj_id = ObjectId::new(1, 0);
453 let key = EncryptionKey::new(vec![0x01; 16]);
454
455 let encrypted = handler
457 .process_stream_encryption(&dict, original_data, &obj_id, &key, true)
458 .unwrap();
459
460 let decrypted = handler
462 .process_stream_encryption(&dict, &encrypted, &obj_id, &key, false)
463 .unwrap();
464
465 assert_eq!(decrypted, original_data);
466 }
467}