1use crate::encryption::{
7 CryptFilterManager, EmbeddedFileEncryption, EncryptionDictionary, EncryptionKey,
8 SecurityHandler, StandardSecurityHandler,
9};
10use crate::error::{PdfError, Result};
11use crate::objects::{Dictionary, Object, ObjectId, Stream};
12use std::sync::Arc;
13
14pub struct ObjectEncryptor {
16 filter_manager: Arc<CryptFilterManager>,
18 encryption_key: EncryptionKey,
20 encrypt_metadata: bool,
22 embedded_file_handler: Option<EmbeddedFileEncryption>,
24}
25
26impl ObjectEncryptor {
27 pub fn new(
29 filter_manager: Arc<CryptFilterManager>,
30 encryption_key: EncryptionKey,
31 encrypt_metadata: bool,
32 ) -> Self {
33 Self {
34 filter_manager,
35 encryption_key,
36 encrypt_metadata,
37 embedded_file_handler: None,
38 }
39 }
40
41 pub fn with_embedded_files(
43 filter_manager: Arc<CryptFilterManager>,
44 encryption_key: EncryptionKey,
45 encrypt_metadata: bool,
46 eff_filter: Option<String>,
47 ) -> Self {
48 let embedded_file_handler = Some(EmbeddedFileEncryption::new(
49 eff_filter,
50 encrypt_metadata,
51 filter_manager.clone(),
52 ));
53
54 Self {
55 filter_manager,
56 encryption_key,
57 encrypt_metadata,
58 embedded_file_handler,
59 }
60 }
61
62 pub fn encrypt_object(&self, object: &mut Object, obj_id: &ObjectId) -> Result<()> {
64 match object {
65 Object::String(s) => {
66 if !self.should_encrypt_string(s) {
68 return Ok(());
69 }
70
71 let encrypted = self.filter_manager.encrypt_string(
72 s.as_bytes(),
73 obj_id,
74 None,
75 &self.encryption_key,
76 )?;
77
78 *object = Object::ByteString(encrypted);
80 }
81 Object::ByteString(bytes) => {
82 let encrypted = self.filter_manager.encrypt_string(
83 bytes,
84 obj_id,
85 None,
86 &self.encryption_key,
87 )?;
88 *bytes = encrypted;
89 }
90 Object::Stream(dict, data) => {
91 let mut stream = Stream::with_dictionary(dict.clone(), data.clone());
93 self.encrypt_stream(&mut stream, obj_id)?;
94
95 *object = Object::Stream(stream.dictionary().clone(), stream.data().to_vec());
97 }
98 Object::Dictionary(dict) => {
99 self.encrypt_dictionary(dict, obj_id)?;
100 }
101 Object::Array(array) => {
102 for item in array.iter_mut() {
103 self.encrypt_object(item, obj_id)?;
104 }
105 }
106 Object::Reference(_) => {
107 }
109 _ => {
110 }
112 }
113
114 Ok(())
115 }
116
117 pub fn decrypt_object(&self, object: &mut Object, obj_id: &ObjectId) -> Result<()> {
119 match object {
120 Object::String(s) => {
121 if !self.should_encrypt_string(s) {
123 return Ok(());
124 }
125
126 let decrypted = self.filter_manager.decrypt_string(
127 s.as_bytes(),
128 obj_id,
129 None,
130 &self.encryption_key,
131 )?;
132
133 *s = String::from_utf8_lossy(&decrypted).to_string();
134 }
135 Object::ByteString(bytes) => {
136 let decrypted = self.filter_manager.decrypt_string(
137 bytes,
138 obj_id,
139 None,
140 &self.encryption_key,
141 )?;
142 *object = Object::String(String::from_utf8_lossy(&decrypted).to_string());
144 }
145 Object::Stream(dict, data) => {
146 let mut stream = Stream::with_dictionary(dict.clone(), data.clone());
148 self.decrypt_stream(&mut stream, obj_id)?;
149
150 *object = Object::Stream(stream.dictionary().clone(), stream.data().to_vec());
152 }
153 Object::Dictionary(dict) => {
154 self.decrypt_dictionary(dict, obj_id)?;
155 }
156 Object::Array(array) => {
157 for item in array.iter_mut() {
158 self.decrypt_object(item, obj_id)?;
159 }
160 }
161 Object::Reference(_) => {
162 }
164 _ => {
165 }
167 }
168
169 Ok(())
170 }
171
172 fn encrypt_stream(&self, stream: &mut Stream, obj_id: &ObjectId) -> Result<()> {
174 if !self.should_encrypt_stream(stream) {
176 return Ok(());
177 }
178
179 let encrypted_data = if let Some(ref handler) = self.embedded_file_handler {
180 handler.process_stream_encryption(
182 stream.dictionary(),
183 stream.data(),
184 obj_id,
185 &self.encryption_key,
186 true, )?
188 } else {
189 self.filter_manager.encrypt_stream(
191 stream.data(),
192 obj_id,
193 stream.dictionary(),
194 &self.encryption_key,
195 )?
196 };
197
198 *stream.data_mut() = encrypted_data;
199
200 if !stream.dictionary().contains_key("Filter") {
202 stream
203 .dictionary_mut()
204 .set("Filter", Object::Name("Crypt".to_string()));
205 } else if let Some(Object::Array(filters)) = stream.dictionary_mut().get_mut("Filter") {
206 filters.push(Object::Name("Crypt".to_string()));
208 }
209
210 Ok(())
211 }
212
213 fn decrypt_stream(&self, stream: &mut Stream, obj_id: &ObjectId) -> Result<()> {
215 if !self.should_encrypt_stream(stream) {
217 return Ok(());
218 }
219
220 let decrypted_data = if let Some(ref handler) = self.embedded_file_handler {
221 handler.process_stream_encryption(
223 stream.dictionary(),
224 stream.data(),
225 obj_id,
226 &self.encryption_key,
227 false, )?
229 } else {
230 self.filter_manager.decrypt_stream(
232 stream.data(),
233 obj_id,
234 stream.dictionary(),
235 &self.encryption_key,
236 )?
237 };
238
239 *stream.data_mut() = decrypted_data;
240
241 if let Some(Object::Array(filters)) = stream.dictionary_mut().get_mut("Filter") {
243 filters.retain(|f| {
244 if let Object::Name(name) = f {
245 name != "Crypt"
246 } else {
247 true
248 }
249 });
250
251 if filters.is_empty() {
253 stream.dictionary_mut().remove("Filter");
254 }
255 } else if let Some(Object::Name(name)) = stream.dictionary().get("Filter") {
256 if name == "Crypt" {
257 stream.dictionary_mut().remove("Filter");
258 }
259 }
260
261 Ok(())
262 }
263
264 fn encrypt_dictionary(&self, dict: &mut Dictionary, obj_id: &ObjectId) -> Result<()> {
266 let keys: Vec<String> = dict.keys().cloned().collect();
268
269 for key in keys {
270 if self.should_skip_dictionary_key(&key) {
272 continue;
273 }
274
275 if let Some(value) = dict.get_mut(&key) {
276 self.encrypt_object(value, obj_id)?;
277 }
278 }
279
280 Ok(())
281 }
282
283 fn decrypt_dictionary(&self, dict: &mut Dictionary, obj_id: &ObjectId) -> Result<()> {
285 let keys: Vec<String> = dict.keys().cloned().collect();
287
288 for key in keys {
289 if self.should_skip_dictionary_key(&key) {
291 continue;
292 }
293
294 if let Some(value) = dict.get_mut(&key) {
295 self.decrypt_object(value, obj_id)?;
296 }
297 }
298
299 Ok(())
300 }
301
302 fn should_encrypt_string(&self, _s: &str) -> bool {
304 true
306 }
307
308 fn should_encrypt_stream(&self, stream: &Stream) -> bool {
310 if !self.encrypt_metadata {
312 if let Some(Object::Name(type_name)) = stream.dictionary().get("Type") {
313 if type_name == "Metadata" {
314 return false;
315 }
316 }
317 }
318
319 if let Some(filter) = stream.dictionary().get("Filter") {
321 match filter {
322 Object::Name(name) => {
323 if name == "Crypt" {
324 return false;
325 }
326 }
327 Object::Array(filters) => {
328 for f in filters {
329 if let Object::Name(name) = f {
330 if name == "Crypt" {
331 return false;
332 }
333 }
334 }
335 }
336 _ => {}
337 }
338 }
339
340 true
341 }
342
343 fn should_skip_dictionary_key(&self, key: &str) -> bool {
345 matches!(
347 key,
348 "Length" | "Filter" | "DecodeParms" | "Encrypt" | "ID" | "O" | "U" | "P" | "Perms"
349 )
350 }
351}
352
353pub struct DocumentEncryption {
355 pub encryption_dict: EncryptionDictionary,
357 pub encryptor: ObjectEncryptor,
359}
360
361impl DocumentEncryption {
362 pub fn new(
364 encryption_dict: EncryptionDictionary,
365 user_password: &str,
366 file_id: Option<&[u8]>,
367 ) -> Result<Self> {
368 let handler: Box<dyn SecurityHandler> = match encryption_dict.r {
370 2 | 3 => Box::new(StandardSecurityHandler::rc4_128bit()),
371 4 => Box::new(StandardSecurityHandler {
372 revision: crate::encryption::SecurityHandlerRevision::R4,
373 key_length: encryption_dict.length.unwrap_or(16) as usize,
374 }),
375 5 => Box::new(StandardSecurityHandler::aes_256_r5()),
376 6 => Box::new(StandardSecurityHandler::aes_256_r6()),
377 _ => {
378 return Err(PdfError::EncryptionError(format!(
379 "Unsupported encryption revision: {}",
380 encryption_dict.r
381 )));
382 }
383 };
384
385 let user_pwd = crate::encryption::UserPassword(user_password.to_string());
387 let encryption_key = if encryption_dict.r <= 4 {
388 StandardSecurityHandler {
389 revision: match encryption_dict.r {
390 2 => crate::encryption::SecurityHandlerRevision::R2,
391 3 => crate::encryption::SecurityHandlerRevision::R3,
392 4 => crate::encryption::SecurityHandlerRevision::R4,
393 _ => unreachable!(),
394 },
395 key_length: encryption_dict.length.unwrap_or(16) as usize,
396 }
397 .compute_encryption_key(
398 &user_pwd,
399 &encryption_dict.o,
400 encryption_dict.p,
401 file_id,
402 )?
403 } else {
404 EncryptionKey::new(vec![0u8; 32])
407 };
408
409 let mut filter_manager = CryptFilterManager::new(
411 handler,
412 encryption_dict
413 .stm_f
414 .as_ref()
415 .map(|f| match f {
416 crate::encryption::StreamFilter::StdCF => "StdCF".to_string(),
417 crate::encryption::StreamFilter::Identity => "Identity".to_string(),
418 crate::encryption::StreamFilter::Custom(name) => name.clone(),
419 })
420 .unwrap_or_else(|| "StdCF".to_string()),
421 encryption_dict
422 .str_f
423 .as_ref()
424 .map(|f| match f {
425 crate::encryption::StringFilter::StdCF => "StdCF".to_string(),
426 crate::encryption::StringFilter::Identity => "Identity".to_string(),
427 crate::encryption::StringFilter::Custom(name) => name.clone(),
428 })
429 .unwrap_or_else(|| "StdCF".to_string()),
430 );
431
432 if let Some(ref filters) = encryption_dict.cf {
434 for filter in filters {
435 filter_manager.add_filter(crate::encryption::FunctionalCryptFilter {
436 name: filter.name.clone(),
437 method: filter.method,
438 length: filter.length,
439 auth_event: crate::encryption::AuthEvent::DocOpen,
440 recipients: None,
441 });
442 }
443 }
444
445 let encryptor = ObjectEncryptor::new(
446 Arc::new(filter_manager),
447 encryption_key,
448 encryption_dict.encrypt_metadata,
449 );
450
451 Ok(Self {
452 encryption_dict,
453 encryptor,
454 })
455 }
456
457 pub fn encrypt_objects(&self, objects: &mut [(ObjectId, Object)]) -> Result<()> {
459 for (obj_id, obj) in objects.iter_mut() {
460 if self.is_encryption_dict_object(obj) {
462 continue;
463 }
464
465 self.encryptor.encrypt_object(obj, obj_id)?;
466 }
467
468 Ok(())
469 }
470
471 pub fn decrypt_objects(&self, objects: &mut [(ObjectId, Object)]) -> Result<()> {
473 for (obj_id, obj) in objects.iter_mut() {
474 if self.is_encryption_dict_object(obj) {
476 continue;
477 }
478
479 self.encryptor.decrypt_object(obj, obj_id)?;
480 }
481
482 Ok(())
483 }
484
485 fn is_encryption_dict_object(&self, obj: &Object) -> bool {
487 if let Object::Dictionary(dict) = obj {
488 if let Some(Object::Name(filter)) = dict.get("Filter") {
490 return filter == "Standard";
491 }
492 }
493 false
494 }
495}
496
497#[cfg(test)]
498mod tests {
499 use super::*;
500 use crate::encryption::Permissions;
501
502 fn create_test_encryptor() -> ObjectEncryptor {
503 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
504 let mut filter_manager =
505 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
506
507 filter_manager.add_filter(crate::encryption::FunctionalCryptFilter {
509 name: "StdCF".to_string(),
510 method: crate::encryption::CryptFilterMethod::V2,
511 length: Some(16),
512 auth_event: crate::encryption::AuthEvent::DocOpen,
513 recipients: None,
514 });
515
516 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
517
518 ObjectEncryptor::new(Arc::new(filter_manager), encryption_key, true)
519 }
520
521 #[test]
522 fn test_encrypt_string_object() {
523 let encryptor = create_test_encryptor();
524 let obj_id = ObjectId::new(1, 0);
525
526 let mut obj = Object::String("Test string".to_string());
527 let original = obj.clone();
528
529 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
530
531 assert_ne!(obj, original);
533 }
534
535 #[test]
536 fn test_encrypt_array_object() {
537 let encryptor = create_test_encryptor();
538 let obj_id = ObjectId::new(1, 0);
539
540 let mut obj = Object::Array(vec![
541 Object::String("String 1".to_string()),
542 Object::Integer(42),
543 Object::String("String 2".to_string()),
544 ]);
545
546 let original = obj.clone();
547 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
548
549 assert_ne!(obj, original);
551
552 if let Object::Array(array) = &obj {
554 assert_eq!(array[1], Object::Integer(42));
555 }
556 }
557
558 #[test]
559 fn test_encrypt_dictionary_object() {
560 let encryptor = create_test_encryptor();
561 let obj_id = ObjectId::new(1, 0);
562
563 let mut dict = Dictionary::new();
564 dict.set("Title", Object::String("Test Title".to_string()));
565 dict.set("Length", Object::Integer(100)); dict.set("Filter", Object::Name("FlateDecode".to_string())); let mut obj = Object::Dictionary(dict);
569 let original = obj.clone();
570
571 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
572
573 assert_ne!(obj, original);
575
576 if let Object::Dictionary(dict) = &obj {
578 assert_eq!(dict.get("Length"), Some(&Object::Integer(100)));
579 assert_eq!(
580 dict.get("Filter"),
581 Some(&Object::Name("FlateDecode".to_string()))
582 );
583 }
584 }
585
586 #[test]
587 fn test_encrypt_stream_object() {
588 let encryptor = create_test_encryptor();
589 let obj_id = ObjectId::new(1, 0);
590
591 let dict = Dictionary::new();
592 let data = b"Stream data content".to_vec();
593 let original_data = data.clone();
594
595 let mut obj = Object::Stream(dict, data);
596 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
597
598 if let Object::Stream(dict, data) = &obj {
599 assert_ne!(data, &original_data);
601
602 assert_eq!(dict.get("Filter"), Some(&Object::Name("Crypt".to_string())));
604 }
605 }
606
607 #[test]
608 fn test_skip_metadata_stream() {
609 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
610 let filter_manager =
611 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
612
613 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
614
615 let encryptor = ObjectEncryptor::new(
616 Arc::new(filter_manager),
617 encryption_key,
618 false, );
620
621 let obj_id = ObjectId::new(1, 0);
622
623 let mut dict = Dictionary::new();
624 dict.set("Type", Object::Name("Metadata".to_string()));
625 let data = b"Metadata content".to_vec();
626 let original_data = data.clone();
627
628 let mut obj = Object::Stream(dict, data);
629
630 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
631
632 if let Object::Stream(_, data) = &obj {
633 assert_eq!(data, &original_data);
635 }
636 }
637
638 #[test]
639 fn test_should_skip_dictionary_key() {
640 let encryptor = create_test_encryptor();
641
642 assert!(encryptor.should_skip_dictionary_key("Length"));
643 assert!(encryptor.should_skip_dictionary_key("Filter"));
644 assert!(encryptor.should_skip_dictionary_key("DecodeParms"));
645 assert!(encryptor.should_skip_dictionary_key("Encrypt"));
646 assert!(encryptor.should_skip_dictionary_key("ID"));
647 assert!(encryptor.should_skip_dictionary_key("O"));
648 assert!(encryptor.should_skip_dictionary_key("U"));
649 assert!(encryptor.should_skip_dictionary_key("P"));
650 assert!(encryptor.should_skip_dictionary_key("Perms"));
651
652 assert!(!encryptor.should_skip_dictionary_key("Title"));
653 assert!(!encryptor.should_skip_dictionary_key("Author"));
654 assert!(!encryptor.should_skip_dictionary_key("Subject"));
655 }
656
657 #[test]
658 fn test_decrypt_object_reverses_encryption() {
659 let encryptor = create_test_encryptor();
660 let obj_id = ObjectId::new(1, 0);
661
662 let original_string = "Test content for encryption";
663 let mut obj = Object::String(original_string.to_string());
664 let original = obj.clone();
665
666 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
668
669 assert_ne!(obj, original);
671
672 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
674
675 if let Object::String(s) = &obj {
679 assert!(!s.is_empty());
681 }
682 }
683
684 #[test]
685 fn test_reference_object_not_encrypted() {
686 let encryptor = create_test_encryptor();
687 let obj_id = ObjectId::new(1, 0);
688
689 let mut obj = Object::Reference(ObjectId::new(5, 0));
690 let original = obj.clone();
691
692 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
693
694 assert_eq!(obj, original);
696 }
697
698 #[test]
699 fn test_already_encrypted_stream_skipped() {
700 let encryptor = create_test_encryptor();
701 let obj_id = ObjectId::new(1, 0);
702
703 let mut dict = Dictionary::new();
704 dict.set("Filter", Object::Name("Crypt".to_string()));
705 let data = b"Already encrypted data".to_vec();
706 let original_data = data.clone();
707
708 let mut obj = Object::Stream(dict, data);
709
710 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
711
712 if let Object::Stream(_, data) = &obj {
713 assert_eq!(data, &original_data);
715 }
716 }
717
718 #[test]
719 fn test_document_encryption_creation() {
720 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
721 vec![0u8; 32],
722 vec![1u8; 32],
723 Permissions::all(),
724 None,
725 );
726
727 let doc_encryption =
728 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
729
730 assert!(doc_encryption.is_ok());
731 }
732
733 #[test]
734 fn test_is_encryption_dict_object() {
735 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
736 vec![0u8; 32],
737 vec![1u8; 32],
738 Permissions::all(),
739 None,
740 );
741
742 let doc_encryption =
743 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
744
745 let mut dict = Dictionary::new();
746 dict.set("Filter", Object::Name("Standard".to_string()));
747 let obj = Object::Dictionary(dict);
748
749 assert!(doc_encryption.is_encryption_dict_object(&obj));
750
751 let normal_obj = Object::String("Not an encryption dict".to_string());
752 assert!(!doc_encryption.is_encryption_dict_object(&normal_obj));
753 }
754
755 #[test]
756 fn test_with_embedded_files_constructor() {
757 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
758 let filter_manager =
759 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
760
761 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
762
763 let encryptor = ObjectEncryptor::with_embedded_files(
764 Arc::new(filter_manager),
765 encryption_key,
766 true,
767 Some("StdCF".to_string()),
768 );
769
770 assert!(encryptor.embedded_file_handler.is_some());
772 }
773
774 #[test]
775 fn test_with_embedded_files_no_filter() {
776 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
777 let filter_manager =
778 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
779
780 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
781
782 let encryptor = ObjectEncryptor::with_embedded_files(
783 Arc::new(filter_manager),
784 encryption_key,
785 false,
786 None,
787 );
788
789 assert!(encryptor.embedded_file_handler.is_some());
791 }
792
793 #[test]
794 fn test_decrypt_string_object() {
795 let encryptor = create_test_encryptor();
796 let obj_id = ObjectId::new(1, 0);
797
798 let mut obj = Object::String("Test string for decryption".to_string());
800 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
801
802 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
804
805 if let Object::String(s) = &obj {
807 assert!(!s.is_empty());
808 } else {
809 panic!("Expected String object");
810 }
811 }
812
813 #[test]
814 fn test_decrypt_array_object() {
815 let encryptor = create_test_encryptor();
816 let obj_id = ObjectId::new(1, 0);
817
818 let mut obj = Object::Array(vec![
819 Object::String("Test 1".to_string()),
820 Object::Integer(123),
821 Object::String("Test 2".to_string()),
822 ]);
823
824 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
826
827 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
829
830 if let Object::Array(array) = &obj {
832 assert_eq!(array.len(), 3);
833 assert_eq!(array[1], Object::Integer(123));
834 } else {
835 panic!("Expected Array object");
836 }
837 }
838
839 #[test]
840 fn test_decrypt_dictionary_object() {
841 let encryptor = create_test_encryptor();
842 let obj_id = ObjectId::new(1, 0);
843
844 let mut dict = Dictionary::new();
845 dict.set("Title", Object::String("Test Title".to_string()));
846 dict.set("Count", Object::Integer(42));
847 dict.set("Length", Object::Integer(100)); let mut obj = Object::Dictionary(dict);
850
851 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
853
854 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
856
857 if let Object::Dictionary(dict) = &obj {
859 assert_eq!(dict.get("Count"), Some(&Object::Integer(42)));
860 assert_eq!(dict.get("Length"), Some(&Object::Integer(100)));
861 } else {
862 panic!("Expected Dictionary object");
863 }
864 }
865
866 #[test]
867 fn test_decrypt_reference_not_changed() {
868 let encryptor = create_test_encryptor();
869 let obj_id = ObjectId::new(1, 0);
870
871 let mut obj = Object::Reference(ObjectId::new(10, 0));
872 let original = obj.clone();
873
874 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
875
876 assert_eq!(obj, original);
878 }
879
880 #[test]
881 fn test_decrypt_other_types_not_changed() {
882 let encryptor = create_test_encryptor();
883 let obj_id = ObjectId::new(1, 0);
884
885 let mut obj = Object::Integer(42);
887 let original = obj.clone();
888 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
889 assert_eq!(obj, original);
890
891 let mut obj = Object::Real(3.14);
893 let original = obj.clone();
894 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
895 assert_eq!(obj, original);
896
897 let mut obj = Object::Boolean(true);
899 let original = obj.clone();
900 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
901 assert_eq!(obj, original);
902
903 let mut obj = Object::Null;
905 let original = obj.clone();
906 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
907 assert_eq!(obj, original);
908
909 let mut obj = Object::Name("TestName".to_string());
911 let original = obj.clone();
912 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
913 assert_eq!(obj, original);
914 }
915
916 #[test]
917 fn test_encrypt_other_types_not_changed() {
918 let encryptor = create_test_encryptor();
919 let obj_id = ObjectId::new(1, 0);
920
921 let mut obj = Object::Integer(999);
923 let original = obj.clone();
924 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
925 assert_eq!(obj, original);
926
927 let mut obj = Object::Real(2.718);
929 let original = obj.clone();
930 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
931 assert_eq!(obj, original);
932
933 let mut obj = Object::Boolean(false);
935 let original = obj.clone();
936 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
937 assert_eq!(obj, original);
938
939 let mut obj = Object::Null;
941 let original = obj.clone();
942 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
943 assert_eq!(obj, original);
944
945 let mut obj = Object::Name("AnotherName".to_string());
947 let original = obj.clone();
948 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
949 assert_eq!(obj, original);
950 }
951
952 #[test]
953 fn test_should_encrypt_stream_with_array_filter_containing_crypt() {
954 let encryptor = create_test_encryptor();
955
956 let mut dict = Dictionary::new();
957 dict.set(
958 "Filter",
959 Object::Array(vec![
960 Object::Name("FlateDecode".to_string()),
961 Object::Name("Crypt".to_string()),
962 ]),
963 );
964
965 let stream = Stream::with_dictionary(dict, vec![1, 2, 3]);
966
967 assert!(!encryptor.should_encrypt_stream(&stream));
969 }
970
971 #[test]
972 fn test_should_encrypt_stream_with_array_filter_without_crypt() {
973 let encryptor = create_test_encryptor();
974
975 let mut dict = Dictionary::new();
976 dict.set(
977 "Filter",
978 Object::Array(vec![
979 Object::Name("FlateDecode".to_string()),
980 Object::Name("ASCII85Decode".to_string()),
981 ]),
982 );
983
984 let stream = Stream::with_dictionary(dict, vec![1, 2, 3]);
985
986 assert!(encryptor.should_encrypt_stream(&stream));
988 }
989
990 #[test]
991 fn test_should_encrypt_stream_with_non_name_filter() {
992 let encryptor = create_test_encryptor();
993
994 let mut dict = Dictionary::new();
995 dict.set("Filter", Object::Integer(123));
997
998 let stream = Stream::with_dictionary(dict, vec![1, 2, 3]);
999
1000 assert!(encryptor.should_encrypt_stream(&stream));
1002 }
1003
1004 #[test]
1005 fn test_should_encrypt_string_always_true() {
1006 let encryptor = create_test_encryptor();
1007
1008 assert!(encryptor.should_encrypt_string("any string"));
1009 assert!(encryptor.should_encrypt_string(""));
1010 assert!(encryptor.should_encrypt_string("special chars: !@#$%"));
1011 }
1012
1013 #[test]
1014 fn test_encrypt_objects_skips_encryption_dict() {
1015 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1016 vec![0u8; 32],
1017 vec![1u8; 32],
1018 Permissions::all(),
1019 None,
1020 );
1021
1022 encryption_dict.cf = Some(vec![crate::encryption::CryptFilter {
1024 name: "StdCF".to_string(),
1025 method: crate::encryption::CryptFilterMethod::V2,
1026 length: Some(16),
1027 }]);
1028
1029 let doc_encryption =
1030 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1031
1032 let mut encrypt_dict = Dictionary::new();
1034 encrypt_dict.set("Filter", Object::Name("Standard".to_string()));
1035 encrypt_dict.set("V", Object::Integer(4));
1036
1037 let mut objects = vec![
1038 (
1039 ObjectId::new(1, 0),
1040 Object::Dictionary(encrypt_dict.clone()),
1041 ),
1042 (
1043 ObjectId::new(2, 0),
1044 Object::String("Normal string".to_string()),
1045 ),
1046 ];
1047
1048 let original_encrypt_dict = objects[0].1.clone();
1049
1050 doc_encryption.encrypt_objects(&mut objects).unwrap();
1051
1052 assert_eq!(objects[0].1, original_encrypt_dict);
1054
1055 assert_ne!(objects[1].1, Object::String("Normal string".to_string()));
1057 }
1058
1059 #[test]
1060 fn test_decrypt_objects_skips_encryption_dict() {
1061 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1062 vec![0u8; 32],
1063 vec![1u8; 32],
1064 Permissions::all(),
1065 None,
1066 );
1067
1068 encryption_dict.cf = Some(vec![crate::encryption::CryptFilter {
1070 name: "StdCF".to_string(),
1071 method: crate::encryption::CryptFilterMethod::V2,
1072 length: Some(16),
1073 }]);
1074
1075 let doc_encryption =
1076 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1077
1078 let mut encrypt_dict = Dictionary::new();
1080 encrypt_dict.set("Filter", Object::Name("Standard".to_string()));
1081 encrypt_dict.set("V", Object::Integer(4));
1082
1083 let mut objects = vec![
1084 (
1085 ObjectId::new(1, 0),
1086 Object::Dictionary(encrypt_dict.clone()),
1087 ),
1088 (
1089 ObjectId::new(2, 0),
1090 Object::String("encrypted content".to_string()),
1091 ),
1092 ];
1093
1094 let original_encrypt_dict = objects[0].1.clone();
1095
1096 doc_encryption.decrypt_objects(&mut objects).unwrap();
1097
1098 assert_eq!(objects[0].1, original_encrypt_dict);
1100 }
1101
1102 #[test]
1103 fn test_document_encryption_unsupported_revision() {
1104 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1105 vec![0u8; 32],
1106 vec![1u8; 32],
1107 Permissions::all(),
1108 None,
1109 );
1110 encryption_dict.r = 99; let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1113
1114 assert!(result.is_err());
1115 if let Err(PdfError::EncryptionError(msg)) = result {
1116 assert!(msg.contains("Unsupported encryption revision"));
1117 }
1118 }
1119
1120 #[test]
1121 fn test_document_encryption_r2() {
1122 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1123 vec![0u8; 32],
1124 vec![1u8; 32],
1125 Permissions::all(),
1126 None,
1127 );
1128 encryption_dict.r = 2;
1129
1130 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1131 assert!(result.is_ok());
1132 }
1133
1134 #[test]
1135 fn test_document_encryption_r4() {
1136 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1137 vec![0u8; 32],
1138 vec![1u8; 32],
1139 Permissions::all(),
1140 None,
1141 );
1142 encryption_dict.r = 4;
1143 encryption_dict.length = Some(16);
1144
1145 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1146 assert!(result.is_ok());
1147 }
1148
1149 #[test]
1150 fn test_document_encryption_r5() {
1151 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1152 vec![0u8; 32],
1153 vec![1u8; 32],
1154 Permissions::all(),
1155 None,
1156 );
1157 encryption_dict.r = 5;
1158
1159 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1160 assert!(result.is_ok());
1161 }
1162
1163 #[test]
1164 fn test_document_encryption_r6() {
1165 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1166 vec![0u8; 32],
1167 vec![1u8; 32],
1168 Permissions::all(),
1169 None,
1170 );
1171 encryption_dict.r = 6;
1172
1173 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1174 assert!(result.is_ok());
1175 }
1176
1177 #[test]
1178 fn test_is_encryption_dict_object_not_dict() {
1179 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1180 vec![0u8; 32],
1181 vec![1u8; 32],
1182 Permissions::all(),
1183 None,
1184 );
1185
1186 let doc_encryption =
1187 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1188
1189 assert!(!doc_encryption.is_encryption_dict_object(&Object::Integer(42)));
1191 assert!(!doc_encryption.is_encryption_dict_object(&Object::Null));
1192 assert!(!doc_encryption.is_encryption_dict_object(&Object::Array(vec![Object::Integer(1)])));
1193 }
1194
1195 #[test]
1196 fn test_is_encryption_dict_object_dict_without_filter() {
1197 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1198 vec![0u8; 32],
1199 vec![1u8; 32],
1200 Permissions::all(),
1201 None,
1202 );
1203
1204 let doc_encryption =
1205 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1206
1207 let mut dict = Dictionary::new();
1209 dict.set("Type", Object::Name("Catalog".to_string()));
1210 let obj = Object::Dictionary(dict);
1211
1212 assert!(!doc_encryption.is_encryption_dict_object(&obj));
1213 }
1214
1215 #[test]
1216 fn test_is_encryption_dict_object_dict_with_different_filter() {
1217 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1218 vec![0u8; 32],
1219 vec![1u8; 32],
1220 Permissions::all(),
1221 None,
1222 );
1223
1224 let doc_encryption =
1225 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1226
1227 let mut dict = Dictionary::new();
1229 dict.set("Filter", Object::Name("FlateDecode".to_string()));
1230 let obj = Object::Dictionary(dict);
1231
1232 assert!(!doc_encryption.is_encryption_dict_object(&obj));
1233 }
1234
1235 #[test]
1236 fn test_nested_array_encryption() {
1237 let encryptor = create_test_encryptor();
1238 let obj_id = ObjectId::new(1, 0);
1239
1240 let mut obj = Object::Array(vec![
1242 Object::Array(vec![
1243 Object::String("Nested 1".to_string()),
1244 Object::String("Nested 2".to_string()),
1245 ]),
1246 Object::String("Outer".to_string()),
1247 ]);
1248
1249 let original = obj.clone();
1250
1251 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
1252
1253 assert_ne!(obj, original);
1255
1256 if let Object::Array(outer) = &obj {
1258 assert_eq!(outer.len(), 2);
1259 if let Object::Array(inner) = &outer[0] {
1260 assert_eq!(inner.len(), 2);
1261 } else {
1262 panic!("Expected nested array");
1263 }
1264 }
1265 }
1266
1267 #[test]
1268 fn test_nested_dictionary_encryption() {
1269 let encryptor = create_test_encryptor();
1270 let obj_id = ObjectId::new(1, 0);
1271
1272 let mut inner_dict = Dictionary::new();
1273 inner_dict.set("InnerTitle", Object::String("Inner value".to_string()));
1274
1275 let mut outer_dict = Dictionary::new();
1276 outer_dict.set("OuterTitle", Object::String("Outer value".to_string()));
1277 outer_dict.set("Nested", Object::Dictionary(inner_dict));
1278
1279 let mut obj = Object::Dictionary(outer_dict);
1280 let original = obj.clone();
1281
1282 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
1283
1284 assert_ne!(obj, original);
1286
1287 if let Object::Dictionary(dict) = &obj {
1289 assert!(dict.contains_key("OuterTitle"));
1290 assert!(dict.contains_key("Nested"));
1291 if let Some(Object::Dictionary(nested)) = dict.get("Nested") {
1292 assert!(nested.contains_key("InnerTitle"));
1293 } else {
1294 panic!("Expected nested dictionary");
1295 }
1296 }
1297 }
1298
1299 #[test]
1300 fn test_document_encryption_with_crypt_filters() {
1301 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1302 vec![0u8; 32],
1303 vec![1u8; 32],
1304 Permissions::all(),
1305 None,
1306 );
1307
1308 encryption_dict.cf = Some(vec![crate::encryption::CryptFilter {
1310 name: "StdCF".to_string(),
1311 method: crate::encryption::CryptFilterMethod::V2,
1312 length: Some(16),
1313 }]);
1314
1315 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1316 assert!(result.is_ok());
1317 }
1318
1319 #[test]
1320 fn test_document_encryption_with_custom_stm_str_filters() {
1321 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1322 vec![0u8; 32],
1323 vec![1u8; 32],
1324 Permissions::all(),
1325 None,
1326 );
1327
1328 encryption_dict.stm_f = Some(crate::encryption::StreamFilter::Identity);
1329 encryption_dict.str_f = Some(crate::encryption::StringFilter::Identity);
1330
1331 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1332 assert!(result.is_ok());
1333 }
1334
1335 #[test]
1336 fn test_document_encryption_with_custom_filter_names() {
1337 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1338 vec![0u8; 32],
1339 vec![1u8; 32],
1340 Permissions::all(),
1341 None,
1342 );
1343
1344 encryption_dict.stm_f = Some(crate::encryption::StreamFilter::Custom(
1345 "CustomStm".to_string(),
1346 ));
1347 encryption_dict.str_f = Some(crate::encryption::StringFilter::Custom(
1348 "CustomStr".to_string(),
1349 ));
1350
1351 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1352 assert!(result.is_ok());
1353 }
1354}