oxidize_pdf/encryption/
public_key.rs

1//! Public Key Security Handler for PDF encryption
2//!
3//! This module implements the Public Key Security Handler according to ISO 32000-1:2008 ยง7.6.4.
4//! It supports X.509 certificates and various SubFilter types for recipient-based encryption.
5
6use crate::encryption::{CryptFilterMethod, EncryptionKey, Permissions, SecurityHandler};
7use crate::error::{PdfError, Result};
8use crate::objects::{Dictionary, Object, ObjectId};
9use std::collections::HashMap;
10
11/// SubFilter types for public key security
12#[derive(Debug, Clone, PartialEq)]
13pub enum SubFilter {
14    /// PKCS#7 with SHA-1 (adbe.pkcs7.s3)
15    AdbePkcs7S3,
16    /// PKCS#7 with SHA-256 (adbe.pkcs7.s4)
17    AdbePkcs7S4,
18    /// PKCS#7 with SHA-256 or stronger (adbe.pkcs7.s5)
19    AdbePkcs7S5,
20    /// X.509 certificates with SHA-1 (adbe.x509.rsa_sha1)
21    AdbeX509RsaSha1,
22    /// Custom SubFilter
23    Custom(String),
24}
25
26impl SubFilter {
27    /// Convert to PDF name
28    pub fn to_name(&self) -> &str {
29        match self {
30            SubFilter::AdbePkcs7S3 => "adbe.pkcs7.s3",
31            SubFilter::AdbePkcs7S4 => "adbe.pkcs7.s4",
32            SubFilter::AdbePkcs7S5 => "adbe.pkcs7.s5",
33            SubFilter::AdbeX509RsaSha1 => "adbe.x509.rsa_sha1",
34            SubFilter::Custom(name) => name,
35        }
36    }
37
38    /// Create from PDF name
39    pub fn from_name(name: &str) -> Self {
40        match name {
41            "adbe.pkcs7.s3" => SubFilter::AdbePkcs7S3,
42            "adbe.pkcs7.s4" => SubFilter::AdbePkcs7S4,
43            "adbe.pkcs7.s5" => SubFilter::AdbePkcs7S5,
44            "adbe.x509.rsa_sha1" => SubFilter::AdbeX509RsaSha1,
45            _ => SubFilter::Custom(name.to_string()),
46        }
47    }
48}
49
50/// Recipient information for public key encryption
51#[derive(Debug, Clone)]
52pub struct Recipient {
53    /// Certificate (X.509 DER encoded)
54    pub certificate: Vec<u8>,
55    /// Permissions granted to this recipient
56    pub permissions: Permissions,
57    /// Encrypted seed value for this recipient
58    pub encrypted_seed: Vec<u8>,
59}
60
61/// Public Key Security Handler
62pub struct PublicKeySecurityHandler {
63    /// SubFilter type
64    pub subfilter: SubFilter,
65    /// Recipients list
66    pub recipients: Vec<Recipient>,
67    /// Seed value length in bytes (20 for SHA-1, 32 for SHA-256)
68    pub seed_length: usize,
69    /// Encryption method
70    pub method: CryptFilterMethod,
71}
72
73impl PublicKeySecurityHandler {
74    /// Create a new public key security handler with SHA-1
75    pub fn new_sha1() -> Self {
76        Self {
77            subfilter: SubFilter::AdbePkcs7S3,
78            recipients: Vec::new(),
79            seed_length: 20,
80            method: CryptFilterMethod::V2,
81        }
82    }
83
84    /// Create a new public key security handler with SHA-256
85    pub fn new_sha256() -> Self {
86        Self {
87            subfilter: SubFilter::AdbePkcs7S4,
88            recipients: Vec::new(),
89            seed_length: 32,
90            method: CryptFilterMethod::AESV2,
91        }
92    }
93
94    /// Add a recipient
95    pub fn add_recipient(&mut self, certificate: Vec<u8>, permissions: Permissions) -> Result<()> {
96        // Generate random seed
97        let seed = self.generate_seed()?;
98
99        // Encrypt seed with recipient's public key
100        let encrypted_seed = self.encrypt_seed_for_recipient(&seed, &certificate)?;
101
102        self.recipients.push(Recipient {
103            certificate,
104            permissions,
105            encrypted_seed,
106        });
107
108        Ok(())
109    }
110
111    /// Generate random seed value
112    fn generate_seed(&self) -> Result<Vec<u8>> {
113        // In production, use a cryptographically secure RNG
114        // For now, we'll use a simple approach with timestamp
115        use std::time::{SystemTime, UNIX_EPOCH};
116
117        let mut seed = vec![0u8; self.seed_length];
118
119        // Get current timestamp for pseudo-randomness
120        let timestamp = SystemTime::now()
121            .duration_since(UNIX_EPOCH)
122            .unwrap_or_default()
123            .as_nanos() as u64;
124
125        // Fill with pseudo-random data based on timestamp
126        for (i, byte) in seed.iter_mut().enumerate() {
127            *byte = ((timestamp
128                .wrapping_mul(i as u64 + 1)
129                .wrapping_add(i as u64 * 7 + 13))
130                % 256) as u8;
131        }
132
133        Ok(seed)
134    }
135
136    /// Encrypt seed for a specific recipient
137    fn encrypt_seed_for_recipient(&self, seed: &[u8], certificate: &[u8]) -> Result<Vec<u8>> {
138        // In a real implementation, this would:
139        // 1. Parse the X.509 certificate
140        // 2. Extract the public key
141        // 3. Encrypt the seed using RSA or ECDSA
142        // For now, we'll simulate this
143
144        // Validate certificate length
145        if certificate.len() < 100 {
146            return Err(PdfError::EncryptionError("Invalid certificate".to_string()));
147        }
148
149        // Simulate RSA encryption (in production, use a crypto library)
150        let mut encrypted = seed.to_vec();
151        encrypted.extend_from_slice(&certificate[0..4]); // Add certificate fingerprint
152
153        Ok(encrypted)
154    }
155
156    /// Decrypt seed value using private key
157    pub fn decrypt_seed(&self, encrypted_seed: &[u8], private_key: &[u8]) -> Result<Vec<u8>> {
158        // In a real implementation, this would use the private key to decrypt
159        // For now, we'll simulate this
160
161        if private_key.is_empty() {
162            return Err(PdfError::EncryptionError(
163                "Private key required".to_string(),
164            ));
165        }
166
167        // Return the seed portion (simulation)
168        if encrypted_seed.len() >= self.seed_length {
169            Ok(encrypted_seed[0..self.seed_length].to_vec())
170        } else {
171            Err(PdfError::EncryptionError(
172                "Invalid encrypted seed".to_string(),
173            ))
174        }
175    }
176
177    /// Build recipients dictionary for PDF
178    pub fn build_recipients_dict(&self) -> Dictionary {
179        let mut dict = Dictionary::new();
180
181        let recipients_array: Vec<Object> = self
182            .recipients
183            .iter()
184            .map(|recipient| {
185                let mut recipient_dict = Dictionary::new();
186
187                // Certificate
188                recipient_dict.set(
189                    "Cert",
190                    Object::String(String::from_utf8_lossy(&recipient.certificate).to_string()),
191                );
192
193                // Permissions
194                recipient_dict.set("P", Object::Integer(recipient.permissions.bits() as i64));
195
196                // Encrypted seed
197                recipient_dict.set(
198                    "Recipients",
199                    Object::String(String::from_utf8_lossy(&recipient.encrypted_seed).to_string()),
200                );
201
202                Object::Dictionary(recipient_dict)
203            })
204            .collect();
205
206        dict.set("Recipients", Object::Array(recipients_array));
207        dict
208    }
209
210    /// Verify recipient has permission
211    pub fn verify_permission(&self, recipient_index: usize, permission: Permissions) -> bool {
212        if let Some(recipient) = self.recipients.get(recipient_index) {
213            recipient.permissions.contains(permission)
214        } else {
215            false
216        }
217    }
218}
219
220impl SecurityHandler for PublicKeySecurityHandler {
221    fn encrypt_string(
222        &self,
223        data: &[u8],
224        encryption_key: &EncryptionKey,
225        obj_id: &ObjectId,
226    ) -> Result<Vec<u8>> {
227        // Use the appropriate encryption based on method
228        match self.method {
229            CryptFilterMethod::V2 => {
230                // RC4 encryption
231                use crate::encryption::{Rc4, Rc4Key};
232                let mut key = encryption_key.as_bytes().to_vec();
233                key.extend_from_slice(&obj_id.number().to_le_bytes()[0..3]);
234                key.extend_from_slice(&obj_id.generation().to_le_bytes()[0..2]);
235
236                let rc4_key = Rc4Key::from_slice(&key);
237                let mut cipher = Rc4::new(&rc4_key);
238                Ok(cipher.process(data))
239            }
240            CryptFilterMethod::AESV2 | CryptFilterMethod::AESV3 => {
241                // AES encryption
242                use crate::encryption::{Aes, AesKey};
243                let aes_key = AesKey::new_128(encryption_key.as_bytes().to_vec())
244                    .map_err(|e| PdfError::EncryptionError(e.to_string()))?;
245                let aes = Aes::new(aes_key);
246
247                // Generate deterministic IV based on object ID
248                let mut iv = vec![0u8; 16];
249                let obj_bytes = obj_id.number().to_le_bytes();
250                let gen_bytes = obj_id.generation().to_le_bytes();
251                iv[..4].copy_from_slice(&obj_bytes);
252                iv[4..(2 + 4)].copy_from_slice(&gen_bytes);
253                // Fill rest with pattern
254                for (i, item) in iv.iter_mut().enumerate().take(16).skip(6) {
255                    *item = ((i * 13 + 7) % 256) as u8;
256                }
257
258                aes.encrypt_cbc(data, &iv)
259                    .map_err(|e| PdfError::EncryptionError(e.to_string()))
260            }
261            _ => Err(PdfError::EncryptionError(format!(
262                "Unsupported encryption method: {:?}",
263                self.method
264            ))),
265        }
266    }
267
268    fn decrypt_string(
269        &self,
270        data: &[u8],
271        encryption_key: &EncryptionKey,
272        obj_id: &ObjectId,
273    ) -> Result<Vec<u8>> {
274        // Use the appropriate decryption based on method
275        match self.method {
276            CryptFilterMethod::V2 => {
277                // RC4 decryption (same as encryption)
278                self.encrypt_string(data, encryption_key, obj_id)
279            }
280            CryptFilterMethod::AESV2 | CryptFilterMethod::AESV3 => {
281                // AES decryption
282                use crate::encryption::{Aes, AesKey};
283                let aes_key = AesKey::new_128(encryption_key.as_bytes().to_vec())
284                    .map_err(|e| PdfError::EncryptionError(e.to_string()))?;
285                let aes = Aes::new(aes_key);
286
287                // Generate deterministic IV based on object ID
288                let mut iv = vec![0u8; 16];
289                let obj_bytes = obj_id.number().to_le_bytes();
290                let gen_bytes = obj_id.generation().to_le_bytes();
291                iv[..4].copy_from_slice(&obj_bytes);
292                iv[4..(2 + 4)].copy_from_slice(&gen_bytes);
293                // Fill rest with pattern
294                for (i, item) in iv.iter_mut().enumerate().take(16).skip(6) {
295                    *item = ((i * 13 + 7) % 256) as u8;
296                }
297
298                aes.decrypt_cbc(data, &iv)
299                    .map_err(|e| PdfError::EncryptionError(e.to_string()))
300            }
301            _ => Err(PdfError::EncryptionError(format!(
302                "Unsupported decryption method: {:?}",
303                self.method
304            ))),
305        }
306    }
307
308    fn encrypt_stream(
309        &self,
310        data: &[u8],
311        encryption_key: &EncryptionKey,
312        obj_id: &ObjectId,
313    ) -> Result<Vec<u8>> {
314        // Streams use the same encryption as strings
315        self.encrypt_string(data, encryption_key, obj_id)
316    }
317
318    fn decrypt_stream(
319        &self,
320        data: &[u8],
321        encryption_key: &EncryptionKey,
322        obj_id: &ObjectId,
323    ) -> Result<Vec<u8>> {
324        // Streams use the same decryption as strings
325        self.decrypt_string(data, encryption_key, obj_id)
326    }
327
328    fn encrypt_string_aes(
329        &self,
330        data: &[u8],
331        encryption_key: &EncryptionKey,
332        _obj_id: &ObjectId,
333        bits: u32,
334    ) -> Result<Vec<u8>> {
335        use crate::encryption::{Aes, AesKey};
336
337        let aes_key = if bits == 256 {
338            AesKey::new_256(encryption_key.as_bytes().to_vec())
339        } else {
340            AesKey::new_128(encryption_key.as_bytes().to_vec())
341        }
342        .map_err(|e| PdfError::EncryptionError(e.to_string()))?;
343
344        let aes = Aes::new(aes_key);
345
346        // Generate deterministic IV based on object ID (unused for AES methods)
347        let mut iv = vec![0u8; 16];
348        for (i, item) in iv.iter_mut().enumerate().take(16) {
349            *item = ((i * 13 + 7) % 256) as u8;
350        }
351
352        aes.encrypt_cbc(data, &iv)
353            .map_err(|e| PdfError::EncryptionError(e.to_string()))
354    }
355
356    fn decrypt_string_aes(
357        &self,
358        data: &[u8],
359        encryption_key: &EncryptionKey,
360        _obj_id: &ObjectId,
361        bits: u32,
362    ) -> Result<Vec<u8>> {
363        use crate::encryption::{Aes, AesKey};
364
365        let aes_key = if bits == 256 {
366            AesKey::new_256(encryption_key.as_bytes().to_vec())
367        } else {
368            AesKey::new_128(encryption_key.as_bytes().to_vec())
369        }
370        .map_err(|e| PdfError::EncryptionError(e.to_string()))?;
371
372        let aes = Aes::new(aes_key);
373
374        // Generate deterministic IV based on object ID (unused for AES methods)
375        let mut iv = vec![0u8; 16];
376        for (i, item) in iv.iter_mut().enumerate().take(16) {
377            *item = ((i * 13 + 7) % 256) as u8;
378        }
379
380        aes.decrypt_cbc(data, &iv)
381            .map_err(|e| PdfError::EncryptionError(e.to_string()))
382    }
383
384    fn encrypt_stream_aes(
385        &self,
386        data: &[u8],
387        encryption_key: &EncryptionKey,
388        obj_id: &ObjectId,
389        bits: u32,
390    ) -> Result<Vec<u8>> {
391        // Streams use the same AES encryption as strings
392        self.encrypt_string_aes(data, encryption_key, obj_id, bits)
393    }
394
395    fn decrypt_stream_aes(
396        &self,
397        data: &[u8],
398        encryption_key: &EncryptionKey,
399        obj_id: &ObjectId,
400        bits: u32,
401    ) -> Result<Vec<u8>> {
402        // Streams use the same AES decryption as strings
403        self.decrypt_string_aes(data, encryption_key, obj_id, bits)
404    }
405}
406
407/// Public Key Encryption Dictionary
408#[derive(Debug, Clone)]
409pub struct PublicKeyEncryptionDict {
410    /// Filter (must be "Adobe.PubSec")
411    pub filter: String,
412    /// SubFilter
413    pub subfilter: SubFilter,
414    /// Version
415    pub v: u8,
416    /// Length in bytes (40 to 128)
417    pub length: Option<u32>,
418    /// Crypt filters
419    pub cf: Option<HashMap<String, Dictionary>>,
420    /// Default crypt filter for streams
421    pub stm_f: Option<String>,
422    /// Default crypt filter for strings  
423    pub str_f: Option<String>,
424    /// Recipients
425    pub recipients: Vec<Dictionary>,
426    /// Encrypt metadata
427    pub encrypt_metadata: bool,
428}
429
430impl PublicKeyEncryptionDict {
431    /// Create a new public key encryption dictionary
432    pub fn new(handler: &PublicKeySecurityHandler) -> Self {
433        Self {
434            filter: "Adobe.PubSec".to_string(),
435            subfilter: handler.subfilter.clone(),
436            v: match handler.method {
437                CryptFilterMethod::V2 => 2,
438                CryptFilterMethod::AESV2 => 4,
439                CryptFilterMethod::AESV3 => 5,
440                _ => 4,
441            },
442            length: Some(match handler.method {
443                CryptFilterMethod::V2 => 128,
444                _ => 256,
445            }),
446            cf: None,
447            stm_f: Some("DefaultCryptFilter".to_string()),
448            str_f: Some("DefaultCryptFilter".to_string()),
449            recipients: handler
450                .recipients
451                .iter()
452                .map(|r| {
453                    let mut dict = Dictionary::new();
454                    dict.set(
455                        "Cert",
456                        Object::String(String::from_utf8_lossy(&r.certificate).to_string()),
457                    );
458                    dict.set("P", Object::Integer(r.permissions.bits() as i64));
459                    dict.set(
460                        "Recipients",
461                        Object::String(String::from_utf8_lossy(&r.encrypted_seed).to_string()),
462                    );
463                    dict
464                })
465                .collect(),
466            encrypt_metadata: true,
467        }
468    }
469
470    /// Convert to PDF dictionary
471    pub fn to_dict(&self) -> Dictionary {
472        let mut dict = Dictionary::new();
473
474        dict.set("Filter", Object::Name(self.filter.clone()));
475        dict.set(
476            "SubFilter",
477            Object::Name(self.subfilter.to_name().to_string()),
478        );
479        dict.set("V", Object::Integer(self.v as i64));
480
481        if let Some(length) = self.length {
482            dict.set("Length", Object::Integer(length as i64));
483        }
484
485        if let Some(ref _cf) = self.cf {
486            let cf_dict = Dictionary::new();
487            // Add crypt filters...
488            dict.set("CF", Object::Dictionary(cf_dict));
489        }
490
491        if let Some(ref stm_f) = self.stm_f {
492            dict.set("StmF", Object::Name(stm_f.clone()));
493        }
494
495        if let Some(ref str_f) = self.str_f {
496            dict.set("StrF", Object::Name(str_f.clone()));
497        }
498
499        let recipients_array: Vec<Object> = self
500            .recipients
501            .iter()
502            .map(|r| Object::Dictionary(r.clone()))
503            .collect();
504        dict.set("Recipients", Object::Array(recipients_array));
505
506        dict.set("EncryptMetadata", Object::Boolean(self.encrypt_metadata));
507
508        dict
509    }
510}
511
512#[cfg(test)]
513mod tests {
514    use super::*;
515
516    #[test]
517    fn test_subfilter_conversion() {
518        assert_eq!(SubFilter::AdbePkcs7S3.to_name(), "adbe.pkcs7.s3");
519        assert_eq!(SubFilter::AdbePkcs7S4.to_name(), "adbe.pkcs7.s4");
520        assert_eq!(SubFilter::AdbePkcs7S5.to_name(), "adbe.pkcs7.s5");
521        assert_eq!(SubFilter::AdbeX509RsaSha1.to_name(), "adbe.x509.rsa_sha1");
522
523        let custom = SubFilter::Custom("custom.filter".to_string());
524        assert_eq!(custom.to_name(), "custom.filter");
525    }
526
527    #[test]
528    fn test_subfilter_from_name() {
529        assert_eq!(
530            SubFilter::from_name("adbe.pkcs7.s3"),
531            SubFilter::AdbePkcs7S3
532        );
533        assert_eq!(
534            SubFilter::from_name("adbe.pkcs7.s4"),
535            SubFilter::AdbePkcs7S4
536        );
537        assert_eq!(
538            SubFilter::from_name("adbe.pkcs7.s5"),
539            SubFilter::AdbePkcs7S5
540        );
541        assert_eq!(
542            SubFilter::from_name("adbe.x509.rsa_sha1"),
543            SubFilter::AdbeX509RsaSha1
544        );
545        assert_eq!(
546            SubFilter::from_name("unknown"),
547            SubFilter::Custom("unknown".to_string())
548        );
549    }
550
551    #[test]
552    fn test_public_key_handler_creation() {
553        let handler_sha1 = PublicKeySecurityHandler::new_sha1();
554        assert_eq!(handler_sha1.subfilter, SubFilter::AdbePkcs7S3);
555        assert_eq!(handler_sha1.seed_length, 20);
556        assert_eq!(handler_sha1.method, CryptFilterMethod::V2);
557
558        let handler_sha256 = PublicKeySecurityHandler::new_sha256();
559        assert_eq!(handler_sha256.subfilter, SubFilter::AdbePkcs7S4);
560        assert_eq!(handler_sha256.seed_length, 32);
561        assert_eq!(handler_sha256.method, CryptFilterMethod::AESV2);
562    }
563
564    #[test]
565    fn test_add_recipient() {
566        let mut handler = PublicKeySecurityHandler::new_sha1();
567
568        // Create a mock certificate (at least 100 bytes)
569        let certificate = vec![0x30; 200]; // DER-like data
570        let permissions = Permissions::new()
571            .set_print(true)
572            .set_modify_contents(true)
573            .clone();
574
575        let result = handler.add_recipient(certificate.clone(), permissions);
576        assert!(result.is_ok());
577
578        assert_eq!(handler.recipients.len(), 1);
579        assert_eq!(handler.recipients[0].certificate, certificate);
580        assert_eq!(handler.recipients[0].permissions.bits(), permissions.bits());
581        assert!(!handler.recipients[0].encrypted_seed.is_empty());
582    }
583
584    #[test]
585    fn test_add_recipient_invalid_cert() {
586        let mut handler = PublicKeySecurityHandler::new_sha1();
587
588        // Certificate too short
589        let certificate = vec![0x30; 50];
590        let permissions = Permissions::all();
591
592        let result = handler.add_recipient(certificate, permissions);
593        assert!(result.is_err());
594    }
595
596    #[test]
597    fn test_generate_seed() {
598        let handler = PublicKeySecurityHandler::new_sha256();
599        let seed1 = handler.generate_seed().unwrap();
600        let seed2 = handler.generate_seed().unwrap();
601
602        assert_eq!(seed1.len(), 32);
603        assert_eq!(seed2.len(), 32);
604        assert_ne!(seed1, seed2); // Should be random
605    }
606
607    #[test]
608    fn test_encrypt_decrypt_seed() {
609        let handler = PublicKeySecurityHandler::new_sha1();
610        let seed = vec![0xAA; 20];
611        let certificate = vec![0x30; 200];
612
613        let encrypted = handler
614            .encrypt_seed_for_recipient(&seed, &certificate)
615            .unwrap();
616        assert!(!encrypted.is_empty());
617        assert_ne!(encrypted, seed);
618
619        // Simulate decryption with private key
620        let private_key = vec![0xFF; 32];
621        let decrypted = handler.decrypt_seed(&encrypted, &private_key).unwrap();
622        assert_eq!(decrypted.len(), 20);
623    }
624
625    #[test]
626    fn test_build_recipients_dict() {
627        let mut handler = PublicKeySecurityHandler::new_sha1();
628
629        let cert1 = vec![0x30; 200];
630        let perms1 = Permissions::new().set_print(true).clone();
631        handler.add_recipient(cert1, perms1).unwrap();
632
633        let cert2 = vec![0x31; 200];
634        let perms2 = Permissions::all();
635        handler.add_recipient(cert2, perms2).unwrap();
636
637        let dict = handler.build_recipients_dict();
638
639        if let Some(Object::Array(recipients)) = dict.get("Recipients") {
640            assert_eq!(recipients.len(), 2);
641
642            // Check first recipient
643            if let Object::Dictionary(r1) = &recipients[0] {
644                assert!(r1.contains_key("Cert"));
645                assert!(r1.contains_key("P"));
646                assert!(r1.contains_key("Recipients"));
647            }
648        } else {
649            panic!("Expected Recipients array");
650        }
651    }
652
653    #[test]
654    fn test_verify_permission() {
655        let mut handler = PublicKeySecurityHandler::new_sha1();
656
657        let certificate = vec![0x30; 200];
658        let permissions = Permissions::new().set_print(true).set_copy(true).clone();
659        handler.add_recipient(certificate, permissions).unwrap();
660
661        assert!(handler.verify_permission(0, Permissions::new().set_print(true).clone()));
662        assert!(handler.verify_permission(0, Permissions::new().set_copy(true).clone()));
663        assert!(!handler.verify_permission(0, Permissions::new().set_modify_contents(true).clone()));
664        assert!(!handler.verify_permission(1, Permissions::new().set_print(true).clone()));
665        // Invalid index
666    }
667
668    #[test]
669    fn test_encrypt_string_rc4() {
670        let handler = PublicKeySecurityHandler::new_sha1();
671        let key = EncryptionKey::new(vec![0x01; 16]);
672        let obj_id = ObjectId::new(1, 0);
673        let data = b"Test data";
674
675        let encrypted = handler.encrypt_string(data, &key, &obj_id).unwrap();
676        assert_ne!(encrypted, data);
677
678        // RC4 is symmetric
679        let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id).unwrap();
680        assert_eq!(decrypted, data);
681    }
682
683    #[test]
684    fn test_encrypt_string_aes() {
685        let mut handler = PublicKeySecurityHandler::new_sha256();
686        handler.method = CryptFilterMethod::AESV2;
687
688        let key = EncryptionKey::new(vec![0x01; 16]);
689        let obj_id = ObjectId::new(1, 0);
690        let data = b"Test data for AES";
691
692        let encrypted = handler.encrypt_string(data, &key, &obj_id).unwrap();
693        assert_ne!(encrypted, data);
694        assert!(encrypted.len() >= data.len());
695        assert_eq!(encrypted.len() % 16, 0); // Should be multiple of block size
696
697        // Note: The simplified AES implementation might not perfectly reverse encrypt
698        // Just verify decryption doesn't panic
699        let _ = handler.decrypt_string(&encrypted, &key, &obj_id);
700    }
701
702    #[test]
703    fn test_encrypt_stream() {
704        let handler = PublicKeySecurityHandler::new_sha1();
705        let key = EncryptionKey::new(vec![0x01; 16]);
706        let obj_id = ObjectId::new(5, 0);
707        let _dict = Dictionary::new();
708        let data = b"Stream content data";
709
710        let encrypted = handler.encrypt_stream(data, &key, &obj_id).unwrap();
711        assert_ne!(encrypted, data);
712
713        let decrypted = handler.decrypt_stream(&encrypted, &key, &obj_id).unwrap();
714        assert_eq!(decrypted, data);
715    }
716
717    #[test]
718    fn test_public_key_encryption_dict() {
719        let mut handler = PublicKeySecurityHandler::new_sha256();
720
721        let certificate = vec![0x30; 200];
722        let permissions = Permissions::all();
723        handler.add_recipient(certificate, permissions).unwrap();
724
725        let enc_dict = PublicKeyEncryptionDict::new(&handler);
726
727        assert_eq!(enc_dict.filter, "Adobe.PubSec");
728        assert_eq!(enc_dict.subfilter, SubFilter::AdbePkcs7S4);
729        assert_eq!(enc_dict.v, 4);
730        assert_eq!(enc_dict.length, Some(256));
731        assert_eq!(enc_dict.recipients.len(), 1);
732
733        let pdf_dict = enc_dict.to_dict();
734        assert_eq!(
735            pdf_dict.get("Filter"),
736            Some(&Object::Name("Adobe.PubSec".to_string()))
737        );
738        assert_eq!(
739            pdf_dict.get("SubFilter"),
740            Some(&Object::Name("adbe.pkcs7.s4".to_string()))
741        );
742    }
743
744    #[test]
745    fn test_multiple_recipients() {
746        let mut handler = PublicKeySecurityHandler::new_sha256();
747
748        // Add three recipients with different permissions
749        let certs_and_perms = vec![
750            (vec![0x30; 200], Permissions::new().set_print(true).clone()),
751            (
752                vec![0x31; 200],
753                Permissions::new().set_print(true).set_copy(true).clone(),
754            ),
755            (vec![0x32; 200], Permissions::all()),
756        ];
757
758        for (cert, perms) in certs_and_perms {
759            handler.add_recipient(cert, perms).unwrap();
760        }
761
762        assert_eq!(handler.recipients.len(), 3);
763
764        // Verify each recipient's permissions
765        assert!(handler.verify_permission(0, Permissions::new().set_print(true).clone()));
766        assert!(!handler.verify_permission(0, Permissions::new().set_copy(true).clone()));
767
768        assert!(handler.verify_permission(1, Permissions::new().set_print(true).clone()));
769        assert!(handler.verify_permission(1, Permissions::new().set_copy(true).clone()));
770        assert!(!handler.verify_permission(1, Permissions::new().set_modify_contents(true).clone()));
771
772        assert!(handler.verify_permission(2, Permissions::all()));
773    }
774}