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 return Err(PdfError::EncryptionError(format!(
412 "DocumentEncryption::new does not support AES-256 (R{}); \
413 use the reader's EncryptionHandler for R5/R6 key recovery",
414 encryption_dict.r
415 )));
416 };
417
418 let mut filter_manager = CryptFilterManager::new(
420 handler,
421 encryption_dict
422 .stm_f
423 .as_ref()
424 .map(|f| match f {
425 crate::encryption::StreamFilter::StdCF => "StdCF".to_string(),
426 crate::encryption::StreamFilter::Identity => "Identity".to_string(),
427 crate::encryption::StreamFilter::Custom(name) => name.clone(),
428 })
429 .unwrap_or_else(|| "StdCF".to_string()),
430 encryption_dict
431 .str_f
432 .as_ref()
433 .map(|f| match f {
434 crate::encryption::StringFilter::StdCF => "StdCF".to_string(),
435 crate::encryption::StringFilter::Identity => "Identity".to_string(),
436 crate::encryption::StringFilter::Custom(name) => name.clone(),
437 })
438 .unwrap_or_else(|| "StdCF".to_string()),
439 );
440
441 if let Some(ref filters) = encryption_dict.cf {
443 for filter in filters {
444 filter_manager.add_filter(crate::encryption::FunctionalCryptFilter {
445 name: filter.name.clone(),
446 method: filter.method,
447 length: filter.length,
448 auth_event: crate::encryption::AuthEvent::DocOpen,
449 recipients: None,
450 });
451 }
452 }
453
454 let encryptor = ObjectEncryptor::new(
455 Arc::new(filter_manager),
456 encryption_key,
457 encryption_dict.encrypt_metadata,
458 );
459
460 Ok(Self {
461 encryption_dict,
462 encryptor,
463 })
464 }
465
466 pub fn encrypt_objects(&self, objects: &mut [(ObjectId, Object)]) -> Result<()> {
468 for (obj_id, obj) in objects.iter_mut() {
469 if self.is_encryption_dict_object(obj) {
471 continue;
472 }
473
474 self.encryptor.encrypt_object(obj, obj_id)?;
475 }
476
477 Ok(())
478 }
479
480 pub fn decrypt_objects(&self, objects: &mut [(ObjectId, Object)]) -> Result<()> {
482 for (obj_id, obj) in objects.iter_mut() {
483 if self.is_encryption_dict_object(obj) {
485 continue;
486 }
487
488 self.encryptor.decrypt_object(obj, obj_id)?;
489 }
490
491 Ok(())
492 }
493
494 fn is_encryption_dict_object(&self, obj: &Object) -> bool {
496 if let Object::Dictionary(dict) = obj {
497 if let Some(Object::Name(filter)) = dict.get("Filter") {
499 return filter == "Standard";
500 }
501 }
502 false
503 }
504}
505
506#[cfg(test)]
507mod tests {
508 use super::*;
509 use crate::encryption::Permissions;
510
511 fn create_test_encryptor() -> ObjectEncryptor {
512 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
513 let mut filter_manager =
514 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
515
516 filter_manager.add_filter(crate::encryption::FunctionalCryptFilter {
518 name: "StdCF".to_string(),
519 method: crate::encryption::CryptFilterMethod::V2,
520 length: Some(16),
521 auth_event: crate::encryption::AuthEvent::DocOpen,
522 recipients: None,
523 });
524
525 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
526
527 ObjectEncryptor::new(Arc::new(filter_manager), encryption_key, true)
528 }
529
530 #[test]
531 fn test_encrypt_string_object() {
532 let encryptor = create_test_encryptor();
533 let obj_id = ObjectId::new(1, 0);
534
535 let mut obj = Object::String("Test string".to_string());
536 let original = obj.clone();
537
538 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
539
540 assert_ne!(obj, original);
542 }
543
544 #[test]
545 fn test_encrypt_array_object() {
546 let encryptor = create_test_encryptor();
547 let obj_id = ObjectId::new(1, 0);
548
549 let mut obj = Object::Array(vec![
550 Object::String("String 1".to_string()),
551 Object::Integer(42),
552 Object::String("String 2".to_string()),
553 ]);
554
555 let original = obj.clone();
556 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
557
558 assert_ne!(obj, original);
560
561 if let Object::Array(array) = &obj {
563 assert_eq!(array[1], Object::Integer(42));
564 }
565 }
566
567 #[test]
568 fn test_encrypt_dictionary_object() {
569 let encryptor = create_test_encryptor();
570 let obj_id = ObjectId::new(1, 0);
571
572 let mut dict = Dictionary::new();
573 dict.set("Title", Object::String("Test Title".to_string()));
574 dict.set("Length", Object::Integer(100)); dict.set("Filter", Object::Name("FlateDecode".to_string())); let mut obj = Object::Dictionary(dict);
578 let original = obj.clone();
579
580 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
581
582 assert_ne!(obj, original);
584
585 if let Object::Dictionary(dict) = &obj {
587 assert_eq!(dict.get("Length"), Some(&Object::Integer(100)));
588 assert_eq!(
589 dict.get("Filter"),
590 Some(&Object::Name("FlateDecode".to_string()))
591 );
592 }
593 }
594
595 #[test]
596 fn test_encrypt_stream_object() {
597 let encryptor = create_test_encryptor();
598 let obj_id = ObjectId::new(1, 0);
599
600 let dict = Dictionary::new();
601 let data = b"Stream data content".to_vec();
602 let original_data = data.clone();
603
604 let mut obj = Object::Stream(dict, data);
605 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
606
607 if let Object::Stream(dict, data) = &obj {
608 assert_ne!(data, &original_data);
610
611 assert_eq!(dict.get("Filter"), Some(&Object::Name("Crypt".to_string())));
613 }
614 }
615
616 #[test]
617 fn test_skip_metadata_stream() {
618 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
619 let filter_manager =
620 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
621
622 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
623
624 let encryptor = ObjectEncryptor::new(
625 Arc::new(filter_manager),
626 encryption_key,
627 false, );
629
630 let obj_id = ObjectId::new(1, 0);
631
632 let mut dict = Dictionary::new();
633 dict.set("Type", Object::Name("Metadata".to_string()));
634 let data = b"Metadata content".to_vec();
635 let original_data = data.clone();
636
637 let mut obj = Object::Stream(dict, data);
638
639 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
640
641 if let Object::Stream(_, data) = &obj {
642 assert_eq!(data, &original_data);
644 }
645 }
646
647 #[test]
648 fn test_should_skip_dictionary_key() {
649 let encryptor = create_test_encryptor();
650
651 assert!(encryptor.should_skip_dictionary_key("Length"));
652 assert!(encryptor.should_skip_dictionary_key("Filter"));
653 assert!(encryptor.should_skip_dictionary_key("DecodeParms"));
654 assert!(encryptor.should_skip_dictionary_key("Encrypt"));
655 assert!(encryptor.should_skip_dictionary_key("ID"));
656 assert!(encryptor.should_skip_dictionary_key("O"));
657 assert!(encryptor.should_skip_dictionary_key("U"));
658 assert!(encryptor.should_skip_dictionary_key("P"));
659 assert!(encryptor.should_skip_dictionary_key("Perms"));
660
661 assert!(!encryptor.should_skip_dictionary_key("Title"));
662 assert!(!encryptor.should_skip_dictionary_key("Author"));
663 assert!(!encryptor.should_skip_dictionary_key("Subject"));
664 }
665
666 #[test]
667 fn test_decrypt_object_reverses_encryption() {
668 let encryptor = create_test_encryptor();
669 let obj_id = ObjectId::new(1, 0);
670
671 let original_string = "Test content for encryption";
672 let mut obj = Object::String(original_string.to_string());
673 let original = obj.clone();
674
675 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
677
678 assert_ne!(obj, original);
680
681 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
683
684 if let Object::String(s) = &obj {
688 assert!(!s.is_empty());
690 }
691 }
692
693 #[test]
694 fn test_reference_object_not_encrypted() {
695 let encryptor = create_test_encryptor();
696 let obj_id = ObjectId::new(1, 0);
697
698 let mut obj = Object::Reference(ObjectId::new(5, 0));
699 let original = obj.clone();
700
701 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
702
703 assert_eq!(obj, original);
705 }
706
707 #[test]
708 fn test_already_encrypted_stream_skipped() {
709 let encryptor = create_test_encryptor();
710 let obj_id = ObjectId::new(1, 0);
711
712 let mut dict = Dictionary::new();
713 dict.set("Filter", Object::Name("Crypt".to_string()));
714 let data = b"Already encrypted data".to_vec();
715 let original_data = data.clone();
716
717 let mut obj = Object::Stream(dict, data);
718
719 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
720
721 if let Object::Stream(_, data) = &obj {
722 assert_eq!(data, &original_data);
724 }
725 }
726
727 #[test]
728 fn test_document_encryption_creation() {
729 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
730 vec![0u8; 32],
731 vec![1u8; 32],
732 Permissions::all(),
733 None,
734 );
735
736 let doc_encryption =
737 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
738
739 assert!(doc_encryption.is_ok());
740 }
741
742 #[test]
743 fn test_is_encryption_dict_object() {
744 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
745 vec![0u8; 32],
746 vec![1u8; 32],
747 Permissions::all(),
748 None,
749 );
750
751 let doc_encryption =
752 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
753
754 let mut dict = Dictionary::new();
755 dict.set("Filter", Object::Name("Standard".to_string()));
756 let obj = Object::Dictionary(dict);
757
758 assert!(doc_encryption.is_encryption_dict_object(&obj));
759
760 let normal_obj = Object::String("Not an encryption dict".to_string());
761 assert!(!doc_encryption.is_encryption_dict_object(&normal_obj));
762 }
763
764 #[test]
765 fn test_with_embedded_files_constructor() {
766 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
767 let filter_manager =
768 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
769
770 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
771
772 let encryptor = ObjectEncryptor::with_embedded_files(
773 Arc::new(filter_manager),
774 encryption_key,
775 true,
776 Some("StdCF".to_string()),
777 );
778
779 assert!(encryptor.embedded_file_handler.is_some());
781 }
782
783 #[test]
784 fn test_with_embedded_files_no_filter() {
785 let handler = Box::new(StandardSecurityHandler::rc4_128bit());
786 let filter_manager =
787 CryptFilterManager::new(handler, "StdCF".to_string(), "StdCF".to_string());
788
789 let encryption_key = EncryptionKey::new(vec![0u8; 16]);
790
791 let encryptor = ObjectEncryptor::with_embedded_files(
792 Arc::new(filter_manager),
793 encryption_key,
794 false,
795 None,
796 );
797
798 assert!(encryptor.embedded_file_handler.is_some());
800 }
801
802 #[test]
803 fn test_decrypt_string_object() {
804 let encryptor = create_test_encryptor();
805 let obj_id = ObjectId::new(1, 0);
806
807 let mut obj = Object::String("Test string for decryption".to_string());
809 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
810
811 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
813
814 if let Object::String(s) = &obj {
816 assert!(!s.is_empty());
817 } else {
818 panic!("Expected String object");
819 }
820 }
821
822 #[test]
823 fn test_decrypt_array_object() {
824 let encryptor = create_test_encryptor();
825 let obj_id = ObjectId::new(1, 0);
826
827 let mut obj = Object::Array(vec![
828 Object::String("Test 1".to_string()),
829 Object::Integer(123),
830 Object::String("Test 2".to_string()),
831 ]);
832
833 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
835
836 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
838
839 if let Object::Array(array) = &obj {
841 assert_eq!(array.len(), 3);
842 assert_eq!(array[1], Object::Integer(123));
843 } else {
844 panic!("Expected Array object");
845 }
846 }
847
848 #[test]
849 fn test_decrypt_dictionary_object() {
850 let encryptor = create_test_encryptor();
851 let obj_id = ObjectId::new(1, 0);
852
853 let mut dict = Dictionary::new();
854 dict.set("Title", Object::String("Test Title".to_string()));
855 dict.set("Count", Object::Integer(42));
856 dict.set("Length", Object::Integer(100)); let mut obj = Object::Dictionary(dict);
859
860 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
862
863 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
865
866 if let Object::Dictionary(dict) = &obj {
868 assert_eq!(dict.get("Count"), Some(&Object::Integer(42)));
869 assert_eq!(dict.get("Length"), Some(&Object::Integer(100)));
870 } else {
871 panic!("Expected Dictionary object");
872 }
873 }
874
875 #[test]
876 fn test_decrypt_reference_not_changed() {
877 let encryptor = create_test_encryptor();
878 let obj_id = ObjectId::new(1, 0);
879
880 let mut obj = Object::Reference(ObjectId::new(10, 0));
881 let original = obj.clone();
882
883 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
884
885 assert_eq!(obj, original);
887 }
888
889 #[test]
890 fn test_decrypt_other_types_not_changed() {
891 let encryptor = create_test_encryptor();
892 let obj_id = ObjectId::new(1, 0);
893
894 let mut obj = Object::Integer(42);
896 let original = obj.clone();
897 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
898 assert_eq!(obj, original);
899
900 let mut obj = Object::Real(3.14);
902 let original = obj.clone();
903 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
904 assert_eq!(obj, original);
905
906 let mut obj = Object::Boolean(true);
908 let original = obj.clone();
909 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
910 assert_eq!(obj, original);
911
912 let mut obj = Object::Null;
914 let original = obj.clone();
915 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
916 assert_eq!(obj, original);
917
918 let mut obj = Object::Name("TestName".to_string());
920 let original = obj.clone();
921 encryptor.decrypt_object(&mut obj, &obj_id).unwrap();
922 assert_eq!(obj, original);
923 }
924
925 #[test]
926 fn test_encrypt_other_types_not_changed() {
927 let encryptor = create_test_encryptor();
928 let obj_id = ObjectId::new(1, 0);
929
930 let mut obj = Object::Integer(999);
932 let original = obj.clone();
933 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
934 assert_eq!(obj, original);
935
936 let mut obj = Object::Real(2.718);
938 let original = obj.clone();
939 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
940 assert_eq!(obj, original);
941
942 let mut obj = Object::Boolean(false);
944 let original = obj.clone();
945 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
946 assert_eq!(obj, original);
947
948 let mut obj = Object::Null;
950 let original = obj.clone();
951 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
952 assert_eq!(obj, original);
953
954 let mut obj = Object::Name("AnotherName".to_string());
956 let original = obj.clone();
957 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
958 assert_eq!(obj, original);
959 }
960
961 #[test]
962 fn test_should_encrypt_stream_with_array_filter_containing_crypt() {
963 let encryptor = create_test_encryptor();
964
965 let mut dict = Dictionary::new();
966 dict.set(
967 "Filter",
968 Object::Array(vec![
969 Object::Name("FlateDecode".to_string()),
970 Object::Name("Crypt".to_string()),
971 ]),
972 );
973
974 let stream = Stream::with_dictionary(dict, vec![1, 2, 3]);
975
976 assert!(!encryptor.should_encrypt_stream(&stream));
978 }
979
980 #[test]
981 fn test_should_encrypt_stream_with_array_filter_without_crypt() {
982 let encryptor = create_test_encryptor();
983
984 let mut dict = Dictionary::new();
985 dict.set(
986 "Filter",
987 Object::Array(vec![
988 Object::Name("FlateDecode".to_string()),
989 Object::Name("ASCII85Decode".to_string()),
990 ]),
991 );
992
993 let stream = Stream::with_dictionary(dict, vec![1, 2, 3]);
994
995 assert!(encryptor.should_encrypt_stream(&stream));
997 }
998
999 #[test]
1000 fn test_should_encrypt_stream_with_non_name_filter() {
1001 let encryptor = create_test_encryptor();
1002
1003 let mut dict = Dictionary::new();
1004 dict.set("Filter", Object::Integer(123));
1006
1007 let stream = Stream::with_dictionary(dict, vec![1, 2, 3]);
1008
1009 assert!(encryptor.should_encrypt_stream(&stream));
1011 }
1012
1013 #[test]
1014 fn test_should_encrypt_string_always_true() {
1015 let encryptor = create_test_encryptor();
1016
1017 assert!(encryptor.should_encrypt_string("any string"));
1018 assert!(encryptor.should_encrypt_string(""));
1019 assert!(encryptor.should_encrypt_string("special chars: !@#$%"));
1020 }
1021
1022 #[test]
1023 fn test_encrypt_objects_skips_encryption_dict() {
1024 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1025 vec![0u8; 32],
1026 vec![1u8; 32],
1027 Permissions::all(),
1028 None,
1029 );
1030
1031 encryption_dict.cf = Some(vec![crate::encryption::CryptFilter {
1033 name: "StdCF".to_string(),
1034 method: crate::encryption::CryptFilterMethod::V2,
1035 length: Some(16),
1036 }]);
1037
1038 let doc_encryption =
1039 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1040
1041 let mut encrypt_dict = Dictionary::new();
1043 encrypt_dict.set("Filter", Object::Name("Standard".to_string()));
1044 encrypt_dict.set("V", Object::Integer(4));
1045
1046 let mut objects = vec![
1047 (
1048 ObjectId::new(1, 0),
1049 Object::Dictionary(encrypt_dict.clone()),
1050 ),
1051 (
1052 ObjectId::new(2, 0),
1053 Object::String("Normal string".to_string()),
1054 ),
1055 ];
1056
1057 let original_encrypt_dict = objects[0].1.clone();
1058
1059 doc_encryption.encrypt_objects(&mut objects).unwrap();
1060
1061 assert_eq!(objects[0].1, original_encrypt_dict);
1063
1064 assert_ne!(objects[1].1, Object::String("Normal string".to_string()));
1066 }
1067
1068 #[test]
1069 fn test_decrypt_objects_skips_encryption_dict() {
1070 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1071 vec![0u8; 32],
1072 vec![1u8; 32],
1073 Permissions::all(),
1074 None,
1075 );
1076
1077 encryption_dict.cf = Some(vec![crate::encryption::CryptFilter {
1079 name: "StdCF".to_string(),
1080 method: crate::encryption::CryptFilterMethod::V2,
1081 length: Some(16),
1082 }]);
1083
1084 let doc_encryption =
1085 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1086
1087 let mut encrypt_dict = Dictionary::new();
1089 encrypt_dict.set("Filter", Object::Name("Standard".to_string()));
1090 encrypt_dict.set("V", Object::Integer(4));
1091
1092 let mut objects = vec![
1093 (
1094 ObjectId::new(1, 0),
1095 Object::Dictionary(encrypt_dict.clone()),
1096 ),
1097 (
1098 ObjectId::new(2, 0),
1099 Object::String("encrypted content".to_string()),
1100 ),
1101 ];
1102
1103 let original_encrypt_dict = objects[0].1.clone();
1104
1105 doc_encryption.decrypt_objects(&mut objects).unwrap();
1106
1107 assert_eq!(objects[0].1, original_encrypt_dict);
1109 }
1110
1111 #[test]
1112 fn test_document_encryption_unsupported_revision() {
1113 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1114 vec![0u8; 32],
1115 vec![1u8; 32],
1116 Permissions::all(),
1117 None,
1118 );
1119 encryption_dict.r = 99; let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1122
1123 assert!(result.is_err());
1124 if let Err(PdfError::EncryptionError(msg)) = result {
1125 assert!(msg.contains("Unsupported encryption revision"));
1126 }
1127 }
1128
1129 #[test]
1130 fn test_document_encryption_r2() {
1131 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1132 vec![0u8; 32],
1133 vec![1u8; 32],
1134 Permissions::all(),
1135 None,
1136 );
1137 encryption_dict.r = 2;
1138
1139 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1140 assert!(result.is_ok());
1141 }
1142
1143 #[test]
1144 fn test_document_encryption_r4() {
1145 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1146 vec![0u8; 32],
1147 vec![1u8; 32],
1148 Permissions::all(),
1149 None,
1150 );
1151 encryption_dict.r = 4;
1152 encryption_dict.length = Some(16);
1153
1154 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1155 assert!(result.is_ok());
1156 }
1157
1158 #[test]
1159 fn test_document_encryption_r5_rejects_aes256() {
1160 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1164 vec![0u8; 32],
1165 vec![1u8; 32],
1166 Permissions::all(),
1167 None,
1168 );
1169 encryption_dict.r = 5;
1170
1171 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1172 assert!(result.is_err(), "R5 must be rejected, not zero-keyed");
1173 }
1174
1175 #[test]
1176 fn test_document_encryption_r6_rejects_aes256() {
1177 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1178 vec![0u8; 32],
1179 vec![1u8; 32],
1180 Permissions::all(),
1181 None,
1182 );
1183 encryption_dict.r = 6;
1184
1185 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1186 assert!(result.is_err(), "R6 must be rejected, not zero-keyed");
1187 }
1188
1189 #[test]
1190 fn test_is_encryption_dict_object_not_dict() {
1191 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1192 vec![0u8; 32],
1193 vec![1u8; 32],
1194 Permissions::all(),
1195 None,
1196 );
1197
1198 let doc_encryption =
1199 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1200
1201 assert!(!doc_encryption.is_encryption_dict_object(&Object::Integer(42)));
1203 assert!(!doc_encryption.is_encryption_dict_object(&Object::Null));
1204 assert!(!doc_encryption.is_encryption_dict_object(&Object::Array(vec![Object::Integer(1)])));
1205 }
1206
1207 #[test]
1208 fn test_is_encryption_dict_object_dict_without_filter() {
1209 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1210 vec![0u8; 32],
1211 vec![1u8; 32],
1212 Permissions::all(),
1213 None,
1214 );
1215
1216 let doc_encryption =
1217 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1218
1219 let mut dict = Dictionary::new();
1221 dict.set("Type", Object::Name("Catalog".to_string()));
1222 let obj = Object::Dictionary(dict);
1223
1224 assert!(!doc_encryption.is_encryption_dict_object(&obj));
1225 }
1226
1227 #[test]
1228 fn test_is_encryption_dict_object_dict_with_different_filter() {
1229 let encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1230 vec![0u8; 32],
1231 vec![1u8; 32],
1232 Permissions::all(),
1233 None,
1234 );
1235
1236 let doc_encryption =
1237 DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id")).unwrap();
1238
1239 let mut dict = Dictionary::new();
1241 dict.set("Filter", Object::Name("FlateDecode".to_string()));
1242 let obj = Object::Dictionary(dict);
1243
1244 assert!(!doc_encryption.is_encryption_dict_object(&obj));
1245 }
1246
1247 #[test]
1248 fn test_nested_array_encryption() {
1249 let encryptor = create_test_encryptor();
1250 let obj_id = ObjectId::new(1, 0);
1251
1252 let mut obj = Object::Array(vec![
1254 Object::Array(vec![
1255 Object::String("Nested 1".to_string()),
1256 Object::String("Nested 2".to_string()),
1257 ]),
1258 Object::String("Outer".to_string()),
1259 ]);
1260
1261 let original = obj.clone();
1262
1263 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
1264
1265 assert_ne!(obj, original);
1267
1268 if let Object::Array(outer) = &obj {
1270 assert_eq!(outer.len(), 2);
1271 if let Object::Array(inner) = &outer[0] {
1272 assert_eq!(inner.len(), 2);
1273 } else {
1274 panic!("Expected nested array");
1275 }
1276 }
1277 }
1278
1279 #[test]
1280 fn test_nested_dictionary_encryption() {
1281 let encryptor = create_test_encryptor();
1282 let obj_id = ObjectId::new(1, 0);
1283
1284 let mut inner_dict = Dictionary::new();
1285 inner_dict.set("InnerTitle", Object::String("Inner value".to_string()));
1286
1287 let mut outer_dict = Dictionary::new();
1288 outer_dict.set("OuterTitle", Object::String("Outer value".to_string()));
1289 outer_dict.set("Nested", Object::Dictionary(inner_dict));
1290
1291 let mut obj = Object::Dictionary(outer_dict);
1292 let original = obj.clone();
1293
1294 encryptor.encrypt_object(&mut obj, &obj_id).unwrap();
1295
1296 assert_ne!(obj, original);
1298
1299 if let Object::Dictionary(dict) = &obj {
1301 assert!(dict.contains_key("OuterTitle"));
1302 assert!(dict.contains_key("Nested"));
1303 if let Some(Object::Dictionary(nested)) = dict.get("Nested") {
1304 assert!(nested.contains_key("InnerTitle"));
1305 } else {
1306 panic!("Expected nested dictionary");
1307 }
1308 }
1309 }
1310
1311 #[test]
1312 fn test_document_encryption_with_crypt_filters() {
1313 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1314 vec![0u8; 32],
1315 vec![1u8; 32],
1316 Permissions::all(),
1317 None,
1318 );
1319
1320 encryption_dict.cf = Some(vec![crate::encryption::CryptFilter {
1322 name: "StdCF".to_string(),
1323 method: crate::encryption::CryptFilterMethod::V2,
1324 length: Some(16),
1325 }]);
1326
1327 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1328 assert!(result.is_ok());
1329 }
1330
1331 #[test]
1332 fn test_document_encryption_with_custom_stm_str_filters() {
1333 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1334 vec![0u8; 32],
1335 vec![1u8; 32],
1336 Permissions::all(),
1337 None,
1338 );
1339
1340 encryption_dict.stm_f = Some(crate::encryption::StreamFilter::Identity);
1341 encryption_dict.str_f = Some(crate::encryption::StringFilter::Identity);
1342
1343 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1344 assert!(result.is_ok());
1345 }
1346
1347 #[test]
1348 fn test_document_encryption_with_custom_filter_names() {
1349 let mut encryption_dict = crate::encryption::EncryptionDictionary::rc4_128bit(
1350 vec![0u8; 32],
1351 vec![1u8; 32],
1352 Permissions::all(),
1353 None,
1354 );
1355
1356 encryption_dict.stm_f = Some(crate::encryption::StreamFilter::Custom(
1357 "CustomStm".to_string(),
1358 ));
1359 encryption_dict.str_f = Some(crate::encryption::StringFilter::Custom(
1360 "CustomStr".to_string(),
1361 ));
1362
1363 let result = DocumentEncryption::new(encryption_dict, "user_password", Some(b"file_id"));
1364 assert!(result.is_ok());
1365 }
1366}