1#![allow(clippy::needless_range_loop)]
18
19use crate::encryption::{generate_iv, Aes, AesKey, Permissions, Rc4, Rc4Key};
20use crate::error::Result;
21use crate::objects::ObjectId;
22use rand::Rng;
23use sha2::{Digest, Sha256, Sha384, Sha512};
24use subtle::ConstantTimeEq;
25use zeroize::{Zeroize, ZeroizeOnDrop};
26
27const PADDING: [u8; 32] = [
29 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
30 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A,
31];
32
33#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
38pub struct UserPassword(pub String);
39
40#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
45pub struct OwnerPassword(pub String);
46
47#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
52pub struct EncryptionKey {
53 pub key: Vec<u8>,
55}
56
57impl EncryptionKey {
58 pub fn new(key: Vec<u8>) -> Self {
60 Self { key }
61 }
62
63 pub fn len(&self) -> usize {
65 self.key.len()
66 }
67
68 pub fn is_empty(&self) -> bool {
70 self.key.is_empty()
71 }
72
73 pub fn as_bytes(&self) -> &[u8] {
75 &self.key
76 }
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
81pub enum SecurityHandlerRevision {
82 R2 = 2,
84 R3 = 3,
86 R4 = 4,
88 R5 = 5,
90 R6 = 6,
92}
93
94pub struct StandardSecurityHandler {
96 pub revision: SecurityHandlerRevision,
98 pub key_length: usize,
100}
101
102impl StandardSecurityHandler {
103 pub fn rc4_40bit() -> Self {
105 Self {
106 revision: SecurityHandlerRevision::R2,
107 key_length: 5,
108 }
109 }
110
111 pub fn rc4_128bit() -> Self {
113 Self {
114 revision: SecurityHandlerRevision::R3,
115 key_length: 16,
116 }
117 }
118
119 pub fn aes_128_r4() -> Self {
121 Self {
122 revision: SecurityHandlerRevision::R4,
123 key_length: 16,
124 }
125 }
126
127 pub fn aes_256_r5() -> Self {
129 Self {
130 revision: SecurityHandlerRevision::R5,
131 key_length: 32,
132 }
133 }
134
135 pub fn aes_256_r6() -> Self {
137 Self {
138 revision: SecurityHandlerRevision::R6,
139 key_length: 32,
140 }
141 }
142
143 fn pad_password(password: &str) -> [u8; 32] {
145 let mut padded = [0u8; 32];
146 let password_bytes = password.as_bytes();
147 let len = password_bytes.len().min(32);
148
149 padded[..len].copy_from_slice(&password_bytes[..len]);
151
152 if len < 32 {
154 padded[len..].copy_from_slice(&PADDING[..32 - len]);
155 }
156
157 padded
158 }
159
160 pub fn compute_owner_hash(
162 &self,
163 owner_password: &OwnerPassword,
164 user_password: &UserPassword,
165 ) -> Vec<u8> {
166 let owner_pad = Self::pad_password(&owner_password.0);
168 let user_pad = Self::pad_password(&user_password.0);
169
170 let mut hash = md5::compute(&owner_pad).to_vec();
172
173 if self.revision >= SecurityHandlerRevision::R3 {
175 for _ in 0..50 {
176 hash = md5::compute(&hash).to_vec();
177 }
178 }
179
180 let rc4_key = Rc4Key::from_slice(&hash[..self.key_length]);
182
183 let mut result = rc4_encrypt(&rc4_key, &user_pad);
185
186 if self.revision >= SecurityHandlerRevision::R3 {
188 for i in 1..=19 {
189 let mut key_bytes = hash[..self.key_length].to_vec();
190 for j in 0..self.key_length {
191 key_bytes[j] ^= i as u8;
192 }
193 let iter_key = Rc4Key::from_slice(&key_bytes);
194 result = rc4_encrypt(&iter_key, &result);
195 }
196 }
197
198 result
199 }
200
201 pub fn compute_user_hash(
203 &self,
204 user_password: &UserPassword,
205 owner_hash: &[u8],
206 permissions: Permissions,
207 file_id: Option<&[u8]>,
208 ) -> Result<Vec<u8>> {
209 self.compute_user_hash_with_metadata(user_password, owner_hash, permissions, file_id, true)
210 }
211
212 pub(crate) fn compute_user_hash_with_metadata(
217 &self,
218 user_password: &UserPassword,
219 owner_hash: &[u8],
220 permissions: Permissions,
221 file_id: Option<&[u8]>,
222 encrypt_metadata: bool,
223 ) -> Result<Vec<u8>> {
224 if matches!(
228 self.revision,
229 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6
230 ) {
231 let aes_key =
232 self.compute_aes_encryption_key(user_password, owner_hash, permissions, file_id)?;
233 return Ok(sha256(&aes_key.key));
234 }
235
236 let padded = Self::pad_password(&user_password.0);
237 self.compute_user_hash_from_padded(
238 &padded,
239 owner_hash,
240 permissions,
241 file_id,
242 encrypt_metadata,
243 )
244 }
245
246 pub(crate) fn compute_user_hash_from_padded(
257 &self,
258 padded: &[u8],
259 owner_hash: &[u8],
260 permissions: Permissions,
261 file_id: Option<&[u8]>,
262 encrypt_metadata: bool,
263 ) -> Result<Vec<u8>> {
264 let key = self.compute_key_from_padded(
266 padded,
267 owner_hash,
268 permissions,
269 file_id,
270 encrypt_metadata,
271 )?;
272
273 match self.revision {
274 SecurityHandlerRevision::R2 => {
275 let rc4_key = Rc4Key::from_slice(&key.key);
277 Ok(rc4_encrypt(&rc4_key, &PADDING))
278 }
279 SecurityHandlerRevision::R3 | SecurityHandlerRevision::R4 => {
280 let mut data = Vec::new();
282 data.extend_from_slice(&PADDING);
283
284 if let Some(id) = file_id {
285 data.extend_from_slice(id);
286 }
287
288 let hash = md5::compute(&data);
289
290 let rc4_key = Rc4Key::from_slice(&key.key);
292 let mut result = rc4_encrypt(&rc4_key, hash.as_ref());
293
294 for i in 1..=19 {
296 let mut key_bytes = key.key.clone();
297 for j in 0..key_bytes.len() {
298 key_bytes[j] ^= i as u8;
299 }
300 let iter_key = Rc4Key::from_slice(&key_bytes);
301 result = rc4_encrypt(&iter_key, &result);
302 }
303
304 result.resize(32, 0);
306 Ok(result)
307 }
308 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
309 Err(crate::error::PdfError::EncryptionError(
312 "padded-password user hash is not defined for R5/R6".to_string(),
313 ))
314 }
315 }
316 }
317
318 pub fn compute_encryption_key(
320 &self,
321 user_password: &UserPassword,
322 owner_hash: &[u8],
323 permissions: Permissions,
324 file_id: Option<&[u8]>,
325 ) -> Result<EncryptionKey> {
326 self.compute_encryption_key_with_metadata(
330 user_password,
331 owner_hash,
332 permissions,
333 file_id,
334 true,
335 )
336 }
337
338 pub(crate) fn compute_encryption_key_with_metadata(
345 &self,
346 user_password: &UserPassword,
347 owner_hash: &[u8],
348 permissions: Permissions,
349 file_id: Option<&[u8]>,
350 encrypt_metadata: bool,
351 ) -> Result<EncryptionKey> {
352 match self.revision {
353 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
354 self.compute_aes_encryption_key(user_password, owner_hash, permissions, file_id)
356 }
357 _ => {
358 let padded = Self::pad_password(&user_password.0);
359 self.compute_key_from_padded(
360 &padded,
361 owner_hash,
362 permissions,
363 file_id,
364 encrypt_metadata,
365 )
366 }
367 }
368 }
369
370 pub(crate) fn compute_key_from_padded(
375 &self,
376 padded: &[u8],
377 owner_hash: &[u8],
378 permissions: Permissions,
379 file_id: Option<&[u8]>,
380 encrypt_metadata: bool,
381 ) -> Result<EncryptionKey> {
382 debug_assert!(self.revision <= SecurityHandlerRevision::R4);
383
384 let mut data = Vec::new();
386 data.extend_from_slice(padded);
387 data.extend_from_slice(owner_hash);
388 data.extend_from_slice(&permissions.bits().to_le_bytes());
389
390 if let Some(id) = file_id {
391 data.extend_from_slice(id);
392 }
393
394 if !encrypt_metadata {
399 data.extend_from_slice(&[0xFF, 0xFF, 0xFF, 0xFF]);
400 }
401
402 let mut hash = md5::compute(&data).to_vec();
404
405 if self.revision >= SecurityHandlerRevision::R3 {
407 for _ in 0..50 {
408 hash = md5::compute(&hash[..self.key_length]).to_vec();
409 }
410 }
411
412 hash.truncate(self.key_length);
414
415 Ok(EncryptionKey::new(hash))
416 }
417
418 pub fn encrypt_string(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
420 match self.revision {
421 SecurityHandlerRevision::R4
422 | SecurityHandlerRevision::R5
423 | SecurityHandlerRevision::R6 => {
424 self.encrypt_aes(data, key, obj_id).unwrap_or_default()
426 }
427 _ => {
428 let obj_key = self.compute_object_key(key, obj_id);
430 let rc4_key = Rc4Key::from_slice(&obj_key);
431 rc4_encrypt(&rc4_key, data)
432 }
433 }
434 }
435
436 pub(crate) fn try_decrypt_string(
444 &self,
445 data: &[u8],
446 key: &EncryptionKey,
447 obj_id: &ObjectId,
448 ) -> Result<Vec<u8>> {
449 match self.revision {
450 SecurityHandlerRevision::R4
451 | SecurityHandlerRevision::R5
452 | SecurityHandlerRevision::R6 => self.decrypt_aes(data, key, obj_id),
453 _ => Ok(self.encrypt_string(data, key, obj_id)),
455 }
456 }
457
458 pub(crate) fn try_decrypt_stream(
465 &self,
466 data: &[u8],
467 key: &EncryptionKey,
468 obj_id: &ObjectId,
469 ) -> Result<Vec<u8>> {
470 self.try_decrypt_string(data, key, obj_id)
472 }
473
474 pub fn decrypt_string(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
477 self.try_decrypt_string(data, key, obj_id)
478 .unwrap_or_default()
479 }
480
481 pub fn encrypt_stream(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
483 self.encrypt_string(data, key, obj_id)
484 }
485
486 pub fn decrypt_stream(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
489 self.try_decrypt_stream(data, key, obj_id)
490 .unwrap_or_default()
491 }
492
493 pub fn encrypt_aes(
498 &self,
499 data: &[u8],
500 key: &EncryptionKey,
501 obj_id: &ObjectId,
502 ) -> Result<Vec<u8>> {
503 let aes = match self.revision {
504 SecurityHandlerRevision::R4 => {
505 let obj_key = self.compute_r4_aes_object_key(key, obj_id);
506 Aes::new(AesKey::new_128(obj_key)?)
507 }
508 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
509 let obj_key = self.compute_aes256_object_key(key, obj_id)?;
510 Aes::new(AesKey::new_256(obj_key)?)
511 }
512 _ => {
513 return Err(crate::error::PdfError::EncryptionError(
514 "AES encryption requires Rev 4+ (use RC4 for Rev 2/3)".to_string(),
515 ));
516 }
517 };
518
519 let iv = generate_iv();
520 let mut result = Vec::with_capacity(16 + data.len() + 16);
521 result.extend_from_slice(&iv);
522
523 let encrypted = aes.encrypt_cbc(data, &iv).map_err(|e| {
524 crate::error::PdfError::EncryptionError(format!("AES encryption failed: {e}"))
525 })?;
526
527 result.extend_from_slice(&encrypted);
528 Ok(result)
529 }
530
531 pub fn decrypt_aes(
536 &self,
537 data: &[u8],
538 key: &EncryptionKey,
539 obj_id: &ObjectId,
540 ) -> Result<Vec<u8>> {
541 if data.len() < 16 {
542 return Err(crate::error::PdfError::EncryptionError(
543 "AES encrypted data must be at least 16 bytes (IV)".to_string(),
544 ));
545 }
546
547 let iv = &data[0..16];
548 let encrypted_data = &data[16..];
549
550 let aes = match self.revision {
551 SecurityHandlerRevision::R4 => {
552 let obj_key = self.compute_r4_aes_object_key(key, obj_id);
553 Aes::new(AesKey::new_128(obj_key)?)
554 }
555 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
556 let obj_key = self.compute_aes256_object_key(key, obj_id)?;
557 Aes::new(AesKey::new_256(obj_key)?)
558 }
559 _ => {
560 return Err(crate::error::PdfError::EncryptionError(
561 "AES decryption requires Rev 4+ (use RC4 for Rev 2/3)".to_string(),
562 ));
563 }
564 };
565
566 aes.decrypt_cbc(encrypted_data, iv).map_err(|e| {
567 crate::error::PdfError::EncryptionError(format!("AES decryption failed: {e}"))
568 })
569 }
570
571 fn compute_r4_aes_object_key(&self, key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
576 let mut data = Vec::new();
577 data.extend_from_slice(&key.key);
578 data.extend_from_slice(&obj_id.number().to_le_bytes()[..3]);
579 data.extend_from_slice(&obj_id.generation().to_le_bytes()[..2]);
580 data.extend_from_slice(b"sAlT");
581
582 let hash = md5::compute(&data);
583 let key_len = (key.len() + 5).min(16);
584 hash[..key_len].to_vec()
585 }
586
587 fn compute_aes256_object_key(
597 &self,
598 key: &EncryptionKey,
599 _obj_id: &ObjectId,
600 ) -> Result<Vec<u8>> {
601 if self.revision < SecurityHandlerRevision::R5 {
602 return Err(crate::error::PdfError::EncryptionError(
603 "AESV3 file-key derivation only for Rev 5+".to_string(),
604 ));
605 }
606
607 Ok(key.key.clone())
608 }
609
610 pub fn compute_aes_encryption_key(
612 &self,
613 user_password: &UserPassword,
614 owner_hash: &[u8],
615 permissions: Permissions,
616 file_id: Option<&[u8]>,
617 ) -> Result<EncryptionKey> {
618 if self.revision < SecurityHandlerRevision::R5 {
619 return Err(crate::error::PdfError::EncryptionError(
620 "AES key computation only for Rev 5+".to_string(),
621 ));
622 }
623
624 let mut data = Vec::new();
626
627 let password_bytes = user_password.0.as_bytes();
629 data.extend_from_slice(password_bytes);
630
631 data.extend_from_slice(owner_hash);
633 data.extend_from_slice(&permissions.bits().to_le_bytes());
634
635 if let Some(id) = file_id {
636 data.extend_from_slice(id);
637 }
638
639 let mut hash = sha256(&data);
641
642 for _ in 0..100 {
644 hash = sha256(&hash);
645 }
646
647 hash.truncate(32);
649
650 Ok(EncryptionKey::new(hash))
651 }
652
653 pub fn validate_aes_user_password(
655 &self,
656 password: &UserPassword,
657 user_hash: &[u8],
658 permissions: Permissions,
659 file_id: Option<&[u8]>,
660 ) -> Result<bool> {
661 if self.revision < SecurityHandlerRevision::R5 {
662 return Err(crate::error::PdfError::EncryptionError(
663 "AES password validation only for Rev 5+".to_string(),
664 ));
665 }
666
667 let computed_key =
668 self.compute_aes_encryption_key(password, user_hash, permissions, file_id)?;
669
670 let computed_hash = sha256(&computed_key.key);
672
673 Ok(user_hash.len() >= 32 && computed_hash[..32] == user_hash[..32])
674 }
675
676 pub fn compute_r5_user_hash(&self, user_password: &UserPassword) -> Result<Vec<u8>> {
691 if self.revision != SecurityHandlerRevision::R5 {
692 return Err(crate::error::PdfError::EncryptionError(
693 "R5 user hash only for Revision 5".to_string(),
694 ));
695 }
696
697 let validation_salt = generate_salt(R5_SALT_LENGTH);
699 let key_salt = generate_salt(R5_SALT_LENGTH);
700
701 let mut data = Vec::new();
703 data.extend_from_slice(user_password.0.as_bytes());
704 data.extend_from_slice(&validation_salt);
705
706 let mut hash = sha256(&data);
707
708 for _ in 0..R5_HASH_ITERATIONS {
710 hash = sha256(&hash);
711 }
712
713 let mut u_entry = Vec::with_capacity(48);
715 u_entry.extend_from_slice(&hash[..32]);
716 u_entry.extend_from_slice(&validation_salt);
717 u_entry.extend_from_slice(&key_salt);
718
719 debug_assert_eq!(u_entry.len(), 48);
720 Ok(u_entry)
721 }
722
723 pub fn validate_r5_user_password(
737 &self,
738 password: &UserPassword,
739 u_entry: &[u8],
740 ) -> Result<bool> {
741 if u_entry.len() != U_ENTRY_LENGTH {
742 return Err(crate::error::PdfError::EncryptionError(format!(
743 "R5 U entry must be {} bytes, got {}",
744 U_ENTRY_LENGTH,
745 u_entry.len()
746 )));
747 }
748
749 let validation_salt = &u_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
751
752 let mut data = Vec::new();
754 data.extend_from_slice(password.0.as_bytes());
755 data.extend_from_slice(validation_salt);
756
757 let mut hash = sha256(&data);
758
759 for _ in 0..R5_HASH_ITERATIONS {
761 hash = sha256(&hash);
762 }
763
764 let stored_hash = &u_entry[..U_HASH_LENGTH];
766 let computed_hash = &hash[..U_HASH_LENGTH];
767 Ok(bool::from(computed_hash.ct_eq(stored_hash)))
768 }
769
770 pub fn compute_r5_ue_entry(
780 &self,
781 user_password: &UserPassword,
782 u_entry: &[u8],
783 encryption_key: &EncryptionKey,
784 ) -> Result<Vec<u8>> {
785 if u_entry.len() != U_ENTRY_LENGTH {
786 return Err(crate::error::PdfError::EncryptionError(format!(
787 "U entry must be {} bytes",
788 U_ENTRY_LENGTH
789 )));
790 }
791 if encryption_key.len() != UE_ENTRY_LENGTH {
792 return Err(crate::error::PdfError::EncryptionError(format!(
793 "Encryption key must be {} bytes for R5",
794 UE_ENTRY_LENGTH
795 )));
796 }
797
798 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
800
801 let mut data = Vec::new();
803 data.extend_from_slice(user_password.0.as_bytes());
804 data.extend_from_slice(key_salt);
805
806 let intermediate_key = sha256(&data);
807
808 let aes_key = AesKey::new_256(intermediate_key)?;
811 let aes = Aes::new(aes_key);
812 let iv = [0u8; 16];
813
814 let encrypted = aes
815 .encrypt_cbc_raw(encryption_key.as_bytes(), &iv)
816 .map_err(|e| {
817 crate::error::PdfError::EncryptionError(format!("UE encryption failed: {}", e))
818 })?;
819
820 Ok(encrypted)
822 }
823
824 pub fn recover_r5_encryption_key(
831 &self,
832 user_password: &UserPassword,
833 u_entry: &[u8],
834 ue_entry: &[u8],
835 ) -> Result<EncryptionKey> {
836 if ue_entry.len() != UE_ENTRY_LENGTH {
837 return Err(crate::error::PdfError::EncryptionError(format!(
838 "UE entry must be {} bytes, got {}",
839 UE_ENTRY_LENGTH,
840 ue_entry.len()
841 )));
842 }
843 if u_entry.len() != U_ENTRY_LENGTH {
844 return Err(crate::error::PdfError::EncryptionError(format!(
845 "U entry must be {} bytes",
846 U_ENTRY_LENGTH
847 )));
848 }
849
850 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
852
853 let mut data = Vec::new();
855 data.extend_from_slice(user_password.0.as_bytes());
856 data.extend_from_slice(key_salt);
857
858 let intermediate_key = sha256(&data);
859
860 let aes_key = AesKey::new_256(intermediate_key)?;
863 let aes = Aes::new(aes_key);
864 let iv = [0u8; 16];
865
866 let decrypted = aes.decrypt_cbc_raw(ue_entry, &iv).map_err(|e| {
867 crate::error::PdfError::EncryptionError(format!("UE decryption failed: {}", e))
868 })?;
869
870 Ok(EncryptionKey::new(decrypted))
871 }
872
873 pub fn compute_r6_user_hash(&self, user_password: &UserPassword) -> Result<Vec<u8>> {
888 if self.revision != SecurityHandlerRevision::R6 {
889 return Err(crate::error::PdfError::EncryptionError(
890 "R6 user hash only for Revision 6".to_string(),
891 ));
892 }
893
894 let validation_salt = generate_salt(R6_SALT_LENGTH);
896 let key_salt = generate_salt(R6_SALT_LENGTH);
897
898 let hash = compute_hash_r6_algorithm_2b(
901 user_password.0.as_bytes(),
902 &validation_salt,
903 &[], )?;
905
906 let mut u_entry = Vec::with_capacity(48);
908 u_entry.extend_from_slice(&hash[..32]);
909 u_entry.extend_from_slice(&validation_salt);
910 u_entry.extend_from_slice(&key_salt);
911
912 debug_assert_eq!(u_entry.len(), 48);
913 Ok(u_entry)
914 }
915
916 pub fn validate_r6_user_password(
929 &self,
930 password: &UserPassword,
931 u_entry: &[u8],
932 ) -> Result<bool> {
933 if u_entry.len() != U_ENTRY_LENGTH {
934 return Err(crate::error::PdfError::EncryptionError(format!(
935 "R6 U entry must be {} bytes, got {}",
936 U_ENTRY_LENGTH,
937 u_entry.len()
938 )));
939 }
940
941 let validation_salt = &u_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
943
944 let hash = compute_hash_r6_algorithm_2b(password.0.as_bytes(), validation_salt, &[])?;
947
948 let stored_hash = &u_entry[..U_HASH_LENGTH];
950 let computed_hash = &hash[..U_HASH_LENGTH];
951 Ok(bool::from(computed_hash.ct_eq(stored_hash)))
952 }
953
954 pub fn compute_r6_ue_entry(
961 &self,
962 user_password: &UserPassword,
963 u_entry: &[u8],
964 encryption_key: &EncryptionKey,
965 ) -> Result<Vec<u8>> {
966 if u_entry.len() != U_ENTRY_LENGTH {
967 return Err(crate::error::PdfError::EncryptionError(format!(
968 "U entry must be {} bytes",
969 U_ENTRY_LENGTH
970 )));
971 }
972 if encryption_key.len() != UE_ENTRY_LENGTH {
973 return Err(crate::error::PdfError::EncryptionError(format!(
974 "Encryption key must be {} bytes for R6",
975 UE_ENTRY_LENGTH
976 )));
977 }
978
979 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
981
982 let hash = compute_hash_r6_algorithm_2b(user_password.0.as_bytes(), key_salt, &[])?;
988 let intermediate_key = hash[..U_HASH_LENGTH].to_vec();
989
990 let aes_key = AesKey::new_256(intermediate_key)?;
992 let aes = Aes::new(aes_key);
993 let iv = [0u8; 16];
994
995 let encrypted = aes
996 .encrypt_cbc_raw(encryption_key.as_bytes(), &iv)
997 .map_err(|e| {
998 crate::error::PdfError::EncryptionError(format!("UE encryption failed: {}", e))
999 })?;
1000
1001 Ok(encrypted)
1002 }
1003
1004 pub fn recover_r6_encryption_key(
1011 &self,
1012 user_password: &UserPassword,
1013 u_entry: &[u8],
1014 ue_entry: &[u8],
1015 ) -> Result<EncryptionKey> {
1016 if ue_entry.len() != UE_ENTRY_LENGTH {
1017 return Err(crate::error::PdfError::EncryptionError(format!(
1018 "UE entry must be {} bytes, got {}",
1019 UE_ENTRY_LENGTH,
1020 ue_entry.len()
1021 )));
1022 }
1023 if u_entry.len() != U_ENTRY_LENGTH {
1024 return Err(crate::error::PdfError::EncryptionError(format!(
1025 "U entry must be {} bytes",
1026 U_ENTRY_LENGTH
1027 )));
1028 }
1029
1030 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1032
1033 let hash = compute_hash_r6_algorithm_2b(user_password.0.as_bytes(), key_salt, &[])?;
1040 let intermediate_key = hash[..U_HASH_LENGTH].to_vec();
1041
1042 let aes_key = AesKey::new_256(intermediate_key)?;
1044 let aes = Aes::new(aes_key);
1045 let iv = [0u8; 16];
1046
1047 let decrypted = aes.decrypt_cbc_raw(ue_entry, &iv).map_err(|e| {
1048 crate::error::PdfError::EncryptionError(format!("UE decryption failed: {}", e))
1049 })?;
1050
1051 Ok(EncryptionKey::new(decrypted))
1052 }
1053
1054 pub fn compute_r6_perms_entry(
1070 &self,
1071 permissions: Permissions,
1072 encryption_key: &EncryptionKey,
1073 encrypt_metadata: bool,
1074 ) -> Result<Vec<u8>> {
1075 if self.revision != SecurityHandlerRevision::R6 {
1076 return Err(crate::error::PdfError::EncryptionError(
1077 "Perms entry only for Revision 6".to_string(),
1078 ));
1079 }
1080 if encryption_key.len() != UE_ENTRY_LENGTH {
1081 return Err(crate::error::PdfError::EncryptionError(format!(
1082 "Encryption key must be {} bytes for R6 Perms",
1083 UE_ENTRY_LENGTH
1084 )));
1085 }
1086
1087 let mut plaintext = vec![0u8; PERMS_ENTRY_LENGTH];
1089
1090 let p_bytes = (permissions.bits() as u32).to_le_bytes();
1092 plaintext[PERMS_P_START..PERMS_P_END].copy_from_slice(&p_bytes);
1093
1094 plaintext[PERMS_MARKER_START..PERMS_MARKER_END].copy_from_slice(&PERMS_MARKER);
1096
1097 plaintext[PERMS_LITERAL_START..PERMS_LITERAL_END].copy_from_slice(PERMS_LITERAL);
1099
1100 plaintext[PERMS_ENCRYPT_META_BYTE] = if encrypt_metadata { b'T' } else { b'F' };
1102
1103 let aes_key = AesKey::new_256(encryption_key.key.clone())?;
1107 let aes = Aes::new(aes_key);
1108
1109 let encrypted = aes.encrypt_ecb(&plaintext).map_err(|e| {
1110 crate::error::PdfError::EncryptionError(format!("Perms encryption failed: {}", e))
1111 })?;
1112
1113 Ok(encrypted)
1114 }
1115
1116 pub fn validate_r6_perms(
1126 &self,
1127 perms_entry: &[u8],
1128 encryption_key: &EncryptionKey,
1129 expected_permissions: Permissions,
1130 ) -> Result<bool> {
1131 if perms_entry.len() != PERMS_ENTRY_LENGTH {
1132 return Err(crate::error::PdfError::EncryptionError(format!(
1133 "Perms entry must be {} bytes, got {}",
1134 PERMS_ENTRY_LENGTH,
1135 perms_entry.len()
1136 )));
1137 }
1138 if encryption_key.len() != UE_ENTRY_LENGTH {
1139 return Err(crate::error::PdfError::EncryptionError(format!(
1140 "Encryption key must be {} bytes",
1141 UE_ENTRY_LENGTH
1142 )));
1143 }
1144
1145 let aes_key = AesKey::new_256(encryption_key.key.clone())?;
1147 let aes = Aes::new(aes_key);
1148
1149 let decrypted = aes.decrypt_ecb(perms_entry).map_err(|e| {
1150 crate::error::PdfError::EncryptionError(format!("Perms decryption failed: {}", e))
1151 })?;
1152
1153 if decrypted[PERMS_MARKER_START..PERMS_MARKER_END] != PERMS_MARKER {
1155 return Ok(false);
1156 }
1157
1158 if &decrypted[PERMS_LITERAL_START..PERMS_LITERAL_END] != PERMS_LITERAL {
1160 return Ok(false);
1161 }
1162
1163 let expected_bytes = (expected_permissions.bits() as u32).to_le_bytes();
1165 let actual_bytes = &decrypted[PERMS_P_START..PERMS_P_END];
1166 Ok(bool::from(expected_bytes.ct_eq(actual_bytes)))
1167 }
1168
1169 pub fn extract_r6_encrypt_metadata(
1174 &self,
1175 perms_entry: &[u8],
1176 encryption_key: &EncryptionKey,
1177 ) -> Result<Option<bool>> {
1178 if perms_entry.len() != PERMS_ENTRY_LENGTH || encryption_key.len() != UE_ENTRY_LENGTH {
1179 return Ok(None);
1180 }
1181
1182 let aes_key = AesKey::new_256(encryption_key.key.clone())?;
1183 let aes = Aes::new(aes_key);
1184
1185 let decrypted = match aes.decrypt_ecb(perms_entry) {
1186 Ok(d) => d,
1187 Err(_) => return Ok(None),
1188 };
1189
1190 if decrypted[PERMS_MARKER_START..PERMS_MARKER_END] != PERMS_MARKER
1192 || &decrypted[PERMS_LITERAL_START..PERMS_LITERAL_END] != PERMS_LITERAL
1193 {
1194 return Ok(None);
1195 }
1196
1197 match decrypted[PERMS_ENCRYPT_META_BYTE] {
1199 b'T' => Ok(Some(true)),
1200 b'F' => Ok(Some(false)),
1201 _ => Ok(None), }
1203 }
1204
1205 pub fn compute_r5_owner_hash(
1216 &self,
1217 owner_password: &OwnerPassword,
1218 u_entry: &[u8],
1219 ) -> Result<Vec<u8>> {
1220 if self.revision != SecurityHandlerRevision::R5 {
1221 return Err(crate::error::PdfError::EncryptionError(
1222 "R5 owner hash only for Revision 5".to_string(),
1223 ));
1224 }
1225 if u_entry.len() != U_ENTRY_LENGTH {
1226 return Err(crate::error::PdfError::EncryptionError(format!(
1227 "U entry must be {} bytes for R5 O computation, got {}",
1228 U_ENTRY_LENGTH,
1229 u_entry.len()
1230 )));
1231 }
1232
1233 let validation_salt = generate_salt(R5_SALT_LENGTH);
1235 let key_salt = generate_salt(R5_SALT_LENGTH);
1236
1237 let mut data = Vec::new();
1242 data.extend_from_slice(owner_password.0.as_bytes());
1243 data.extend_from_slice(&validation_salt);
1244 data.extend_from_slice(u_entry);
1245
1246 let hash = sha256(&data);
1247
1248 let mut o_entry = Vec::with_capacity(U_ENTRY_LENGTH);
1250 o_entry.extend_from_slice(&hash[..U_HASH_LENGTH]);
1251 o_entry.extend_from_slice(&validation_salt);
1252 o_entry.extend_from_slice(&key_salt);
1253
1254 debug_assert_eq!(o_entry.len(), U_ENTRY_LENGTH);
1255 Ok(o_entry)
1256 }
1257
1258 pub fn validate_r5_owner_password(
1262 &self,
1263 owner_password: &OwnerPassword,
1264 o_entry: &[u8],
1265 u_entry: &[u8],
1266 ) -> Result<bool> {
1267 if o_entry.len() != U_ENTRY_LENGTH {
1268 return Err(crate::error::PdfError::EncryptionError(format!(
1269 "R5 O entry must be {} bytes, got {}",
1270 U_ENTRY_LENGTH,
1271 o_entry.len()
1272 )));
1273 }
1274 if u_entry.len() != U_ENTRY_LENGTH {
1275 return Err(crate::error::PdfError::EncryptionError(format!(
1276 "R5 U entry must be {} bytes, got {}",
1277 U_ENTRY_LENGTH,
1278 u_entry.len()
1279 )));
1280 }
1281
1282 let validation_salt = &o_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
1284
1285 let mut data = Vec::new();
1288 data.extend_from_slice(owner_password.0.as_bytes());
1289 data.extend_from_slice(validation_salt);
1290 data.extend_from_slice(u_entry);
1291
1292 let hash = sha256(&data);
1293
1294 let stored_hash = &o_entry[..U_HASH_LENGTH];
1296 Ok(bool::from(hash[..U_HASH_LENGTH].ct_eq(stored_hash)))
1297 }
1298
1299 pub fn compute_r5_oe_entry(
1304 &self,
1305 owner_password: &OwnerPassword,
1306 o_entry: &[u8],
1307 u_entry: &[u8],
1308 encryption_key: &[u8],
1309 ) -> Result<Vec<u8>> {
1310 if o_entry.len() != U_ENTRY_LENGTH {
1311 return Err(crate::error::PdfError::EncryptionError(format!(
1312 "O entry must be {} bytes",
1313 U_ENTRY_LENGTH
1314 )));
1315 }
1316 if u_entry.len() != U_ENTRY_LENGTH {
1317 return Err(crate::error::PdfError::EncryptionError(format!(
1318 "U entry must be {} bytes",
1319 U_ENTRY_LENGTH
1320 )));
1321 }
1322 if encryption_key.len() != UE_ENTRY_LENGTH {
1323 return Err(crate::error::PdfError::EncryptionError(format!(
1324 "Encryption key must be {} bytes",
1325 UE_ENTRY_LENGTH
1326 )));
1327 }
1328
1329 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1331
1332 let mut data = Vec::new();
1335 data.extend_from_slice(owner_password.0.as_bytes());
1336 data.extend_from_slice(key_salt);
1337 data.extend_from_slice(u_entry);
1338
1339 let intermediate_key = sha256(&data);
1340
1341 let aes = Aes::new(AesKey::new_256(intermediate_key)?);
1343 let iv = [0u8; 16];
1344
1345 let encrypted = aes.encrypt_cbc_raw(encryption_key, &iv).map_err(|e| {
1346 crate::error::PdfError::EncryptionError(format!("OE encryption failed: {}", e))
1347 })?;
1348
1349 Ok(encrypted[..UE_ENTRY_LENGTH].to_vec())
1351 }
1352
1353 pub fn recover_r5_owner_encryption_key(
1355 &self,
1356 owner_password: &OwnerPassword,
1357 o_entry: &[u8],
1358 u_entry: &[u8],
1359 oe_entry: &[u8],
1360 ) -> Result<Vec<u8>> {
1361 if o_entry.len() != U_ENTRY_LENGTH {
1362 return Err(crate::error::PdfError::EncryptionError(format!(
1363 "O entry must be {} bytes",
1364 U_ENTRY_LENGTH
1365 )));
1366 }
1367 if u_entry.len() != U_ENTRY_LENGTH {
1368 return Err(crate::error::PdfError::EncryptionError(format!(
1369 "U entry must be {} bytes",
1370 U_ENTRY_LENGTH
1371 )));
1372 }
1373 if oe_entry.len() != UE_ENTRY_LENGTH {
1374 return Err(crate::error::PdfError::EncryptionError(format!(
1375 "OE entry must be {} bytes",
1376 UE_ENTRY_LENGTH
1377 )));
1378 }
1379
1380 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1382
1383 let mut data = Vec::new();
1386 data.extend_from_slice(owner_password.0.as_bytes());
1387 data.extend_from_slice(key_salt);
1388 data.extend_from_slice(u_entry);
1389
1390 let intermediate_key = sha256(&data);
1391
1392 let aes = Aes::new(AesKey::new_256(intermediate_key)?);
1394 let iv = [0u8; 16];
1395
1396 let decrypted = aes.decrypt_cbc_raw(oe_entry, &iv).map_err(|e| {
1397 crate::error::PdfError::EncryptionError(format!("OE decryption failed: {}", e))
1398 })?;
1399
1400 Ok(decrypted)
1401 }
1402
1403 pub fn compute_r6_owner_hash(
1407 &self,
1408 owner_password: &OwnerPassword,
1409 u_entry: &[u8],
1410 ) -> Result<Vec<u8>> {
1411 if self.revision != SecurityHandlerRevision::R6 {
1412 return Err(crate::error::PdfError::EncryptionError(
1413 "R6 owner hash only for Revision 6".to_string(),
1414 ));
1415 }
1416 if u_entry.len() != U_ENTRY_LENGTH {
1417 return Err(crate::error::PdfError::EncryptionError(format!(
1418 "U entry must be {} bytes for R6 O computation",
1419 U_ENTRY_LENGTH
1420 )));
1421 }
1422
1423 let validation_salt = generate_salt(R6_SALT_LENGTH);
1425 let key_salt = generate_salt(R6_SALT_LENGTH);
1426
1427 let hash =
1434 compute_hash_r6_algorithm_2b(owner_password.0.as_bytes(), &validation_salt, u_entry)?;
1435
1436 let mut o_entry = Vec::with_capacity(U_ENTRY_LENGTH);
1438 o_entry.extend_from_slice(&hash[..U_HASH_LENGTH]);
1439 o_entry.extend_from_slice(&validation_salt);
1440 o_entry.extend_from_slice(&key_salt);
1441
1442 debug_assert_eq!(o_entry.len(), U_ENTRY_LENGTH);
1443 Ok(o_entry)
1444 }
1445
1446 pub fn validate_r6_owner_password(
1450 &self,
1451 owner_password: &OwnerPassword,
1452 o_entry: &[u8],
1453 u_entry: &[u8],
1454 ) -> Result<bool> {
1455 if o_entry.len() != U_ENTRY_LENGTH {
1456 return Err(crate::error::PdfError::EncryptionError(format!(
1457 "R6 O entry must be {} bytes",
1458 U_ENTRY_LENGTH
1459 )));
1460 }
1461 if u_entry.len() != U_ENTRY_LENGTH {
1462 return Err(crate::error::PdfError::EncryptionError(format!(
1463 "R6 U entry must be {} bytes",
1464 U_ENTRY_LENGTH
1465 )));
1466 }
1467
1468 let validation_salt = &o_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
1470
1471 let hash =
1475 compute_hash_r6_algorithm_2b(owner_password.0.as_bytes(), validation_salt, u_entry)?;
1476
1477 let stored_hash = &o_entry[..U_HASH_LENGTH];
1479 Ok(bool::from(hash[..U_HASH_LENGTH].ct_eq(stored_hash)))
1480 }
1481
1482 pub fn compute_r6_oe_entry(
1486 &self,
1487 owner_password: &OwnerPassword,
1488 o_entry: &[u8],
1489 u_entry: &[u8],
1490 encryption_key: &[u8],
1491 ) -> Result<Vec<u8>> {
1492 if o_entry.len() != U_ENTRY_LENGTH {
1493 return Err(crate::error::PdfError::EncryptionError(format!(
1494 "O entry must be {} bytes",
1495 U_ENTRY_LENGTH
1496 )));
1497 }
1498 if u_entry.len() != U_ENTRY_LENGTH {
1499 return Err(crate::error::PdfError::EncryptionError(format!(
1500 "U entry must be {} bytes",
1501 U_ENTRY_LENGTH
1502 )));
1503 }
1504 if encryption_key.len() != UE_ENTRY_LENGTH {
1505 return Err(crate::error::PdfError::EncryptionError(format!(
1506 "Encryption key must be {} bytes",
1507 UE_ENTRY_LENGTH
1508 )));
1509 }
1510
1511 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1513
1514 let intermediate_key =
1517 compute_hash_r6_algorithm_2b(owner_password.0.as_bytes(), key_salt, u_entry)?;
1518
1519 let aes = Aes::new(AesKey::new_256(intermediate_key[..32].to_vec())?);
1521 let iv = [0u8; 16];
1522
1523 let encrypted = aes.encrypt_cbc_raw(encryption_key, &iv).map_err(|e| {
1524 crate::error::PdfError::EncryptionError(format!("OE encryption failed: {}", e))
1525 })?;
1526
1527 Ok(encrypted[..UE_ENTRY_LENGTH].to_vec())
1528 }
1529
1530 pub fn recover_r6_owner_encryption_key(
1532 &self,
1533 owner_password: &OwnerPassword,
1534 o_entry: &[u8],
1535 u_entry: &[u8],
1536 oe_entry: &[u8],
1537 ) -> Result<Vec<u8>> {
1538 if o_entry.len() != U_ENTRY_LENGTH {
1539 return Err(crate::error::PdfError::EncryptionError(format!(
1540 "O entry must be {} bytes",
1541 U_ENTRY_LENGTH
1542 )));
1543 }
1544 if u_entry.len() != U_ENTRY_LENGTH {
1545 return Err(crate::error::PdfError::EncryptionError(format!(
1546 "U entry must be {} bytes",
1547 U_ENTRY_LENGTH
1548 )));
1549 }
1550 if oe_entry.len() != UE_ENTRY_LENGTH {
1551 return Err(crate::error::PdfError::EncryptionError(format!(
1552 "OE entry must be {} bytes",
1553 UE_ENTRY_LENGTH
1554 )));
1555 }
1556
1557 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1559
1560 let intermediate_key =
1563 compute_hash_r6_algorithm_2b(owner_password.0.as_bytes(), key_salt, u_entry)?;
1564
1565 let aes = Aes::new(AesKey::new_256(intermediate_key[..32].to_vec())?);
1567 let iv = [0u8; 16];
1568
1569 let decrypted = aes.decrypt_cbc_raw(oe_entry, &iv).map_err(|e| {
1570 crate::error::PdfError::EncryptionError(format!("OE decryption failed: {}", e))
1571 })?;
1572
1573 Ok(decrypted)
1574 }
1575
1576 pub fn compute_object_key(&self, key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
1578 let mut data = Vec::new();
1579 data.extend_from_slice(&key.key);
1580 data.extend_from_slice(&obj_id.number().to_le_bytes()[..3]); data.extend_from_slice(&obj_id.generation().to_le_bytes()[..2]); let hash = md5::compute(&data);
1584 let key_len = (key.len() + 5).min(16);
1585 hash[..key_len].to_vec()
1586 }
1587
1588 pub fn validate_user_password(
1593 &self,
1594 password: &UserPassword,
1595 user_hash: &[u8],
1596 owner_hash: &[u8],
1597 permissions: Permissions,
1598 file_id: Option<&[u8]>,
1599 ) -> Result<bool> {
1600 let key = self.compute_encryption_key(password, owner_hash, permissions, file_id)?;
1602
1603 match self.revision {
1604 SecurityHandlerRevision::R2 => {
1605 let rc4_key = Rc4Key::from_slice(&key.key);
1607 let encrypted_padding = rc4_encrypt(&rc4_key, &PADDING);
1608
1609 Ok(user_hash.len() >= 32 && encrypted_padding[..] == user_hash[..32])
1611 }
1612 SecurityHandlerRevision::R3 | SecurityHandlerRevision::R4 => {
1613 let mut data = Vec::new();
1615 data.extend_from_slice(&PADDING);
1616
1617 if let Some(id) = file_id {
1618 data.extend_from_slice(id);
1619 }
1620
1621 let hash = md5::compute(&data);
1622
1623 let rc4_key = Rc4Key::from_slice(&key.key);
1625 let mut encrypted = rc4_encrypt(&rc4_key, hash.as_ref());
1626
1627 for i in 1..=19 {
1629 let mut key_bytes = key.key.clone();
1630 for byte in &mut key_bytes {
1631 *byte ^= i as u8;
1632 }
1633 let iter_key = Rc4Key::from_slice(&key_bytes);
1634 encrypted = rc4_encrypt(&iter_key, &encrypted);
1635 }
1636
1637 Ok(user_hash.len() >= 16 && encrypted[..16] == user_hash[..16])
1639 }
1640 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
1641 self.validate_aes_user_password(password, user_hash, permissions, file_id)
1643 }
1644 }
1645 }
1646
1647 pub fn validate_owner_password(
1664 &self,
1665 owner_password: &OwnerPassword,
1666 owner_hash: &[u8],
1667 _user_password: &UserPassword, _permissions: Permissions,
1669 _file_id: Option<&[u8]>,
1670 u_entry: Option<&[u8]>,
1671 ) -> Result<bool> {
1672 match self.revision {
1673 SecurityHandlerRevision::R2
1674 | SecurityHandlerRevision::R3
1675 | SecurityHandlerRevision::R4 => {
1676 let owner_pad = Self::pad_password(&owner_password.0);
1678
1679 let mut hash = md5::compute(&owner_pad).to_vec();
1681
1682 if self.revision >= SecurityHandlerRevision::R3 {
1684 for _ in 0..50 {
1685 hash = md5::compute(&hash).to_vec();
1686 }
1687 }
1688
1689 let rc4_key = Rc4Key::from_slice(&hash[..self.key_length]);
1691
1692 let mut decrypted = owner_hash[..32].to_vec();
1694
1695 if self.revision >= SecurityHandlerRevision::R3 {
1697 for i in (0..20).rev() {
1698 let mut key_bytes = hash[..self.key_length].to_vec();
1699 for byte in &mut key_bytes {
1700 *byte ^= i as u8;
1701 }
1702 let iter_key = Rc4Key::from_slice(&key_bytes);
1703 decrypted = rc4_encrypt(&iter_key, &decrypted);
1704 }
1705 } else {
1706 decrypted = rc4_encrypt(&rc4_key, &decrypted);
1708 }
1709
1710 let user_pwd_bytes = decrypted
1716 .iter()
1717 .take_while(|&&b| b != 0x28 || decrypted.starts_with(&PADDING))
1718 .copied()
1719 .collect::<Vec<u8>>();
1720
1721 let recovered_user =
1722 UserPassword(String::from_utf8_lossy(&user_pwd_bytes).to_string());
1723
1724 let computed_owner = self.compute_owner_hash(owner_password, &recovered_user);
1726
1727 Ok(computed_owner[..32] == owner_hash[..32])
1729 }
1730 SecurityHandlerRevision::R5 => {
1731 let u = u_entry.ok_or_else(|| {
1734 crate::error::PdfError::EncryptionError(
1735 "R5 owner password validation requires U entry".to_string(),
1736 )
1737 })?;
1738 self.validate_r5_owner_password(owner_password, owner_hash, u)
1739 }
1740 SecurityHandlerRevision::R6 => {
1741 let u = u_entry.ok_or_else(|| {
1743 crate::error::PdfError::EncryptionError(
1744 "R6 owner password validation requires U entry".to_string(),
1745 )
1746 })?;
1747 self.validate_r6_owner_password(owner_password, owner_hash, u)
1748 }
1749 }
1750 }
1751}
1752
1753fn rc4_encrypt(key: &Rc4Key, data: &[u8]) -> Vec<u8> {
1755 let mut cipher = Rc4::new(key);
1756 cipher.process(data)
1757}
1758
1759fn sha256(data: &[u8]) -> Vec<u8> {
1766 Sha256::digest(data).to_vec()
1767}
1768
1769fn sha384(data: &[u8]) -> Vec<u8> {
1774 Sha384::digest(data).to_vec()
1775}
1776
1777fn sha512(data: &[u8]) -> Vec<u8> {
1782 Sha512::digest(data).to_vec()
1783}
1784
1785const ALGORITHM_2B_MIN_ROUNDS: usize = 64;
1791
1792const ALGORITHM_2B_MAX_ROUNDS: usize = 2048;
1794
1795const ALGORITHM_2B_MAX_PASSWORD_LEN: usize = 127;
1798
1799const HASH_SELECTOR_BYTES: usize = 16;
1801
1802pub fn compute_hash_r6_algorithm_2b(
1834 password: &[u8],
1835 salt: &[u8],
1836 u_entry: &[u8],
1837) -> Result<Vec<u8>> {
1838 if password.len() > ALGORITHM_2B_MAX_PASSWORD_LEN {
1840 return Err(crate::error::PdfError::EncryptionError(format!(
1841 "Password too long ({} bytes, max {})",
1842 password.len(),
1843 ALGORITHM_2B_MAX_PASSWORD_LEN
1844 )));
1845 }
1846
1847 let mut input = Vec::with_capacity(password.len() + salt.len() + u_entry.len().min(48));
1849 input.extend_from_slice(password);
1850 input.extend_from_slice(salt);
1851 if !u_entry.is_empty() {
1852 input.extend_from_slice(&u_entry[..u_entry.len().min(48)]);
1853 }
1854
1855 let mut k = sha256(&input);
1856
1857 let mut round: usize = 0;
1859 loop {
1860 let mut k1_unit = Vec::new();
1863 k1_unit.extend_from_slice(password);
1864 k1_unit.extend_from_slice(&k);
1865 if !u_entry.is_empty() {
1866 k1_unit.extend_from_slice(&u_entry[..u_entry.len().min(48)]);
1867 }
1868
1869 let mut k1 = Vec::with_capacity(k1_unit.len() * 64);
1871 for _ in 0..64 {
1872 k1.extend_from_slice(&k1_unit);
1873 }
1874
1875 while k1.len() % 16 != 0 {
1878 k1.push(0);
1879 }
1880
1881 if k.len() < 32 {
1884 while k.len() < 32 {
1886 k.push(0);
1887 }
1888 }
1889
1890 let aes_key = AesKey::new_128(k[..16].to_vec()).map_err(|e| {
1891 crate::error::PdfError::EncryptionError(format!(
1892 "Algorithm 2.B: Failed to create AES key: {}",
1893 e
1894 ))
1895 })?;
1896 let aes = Aes::new(aes_key);
1897 let iv = &k[16..32];
1898
1899 let e = aes.encrypt_cbc_raw(&k1, iv).map_err(|e| {
1900 crate::error::PdfError::EncryptionError(format!(
1901 "Algorithm 2.B: AES encryption failed: {}",
1902 e
1903 ))
1904 })?;
1905
1906 let hash_selector = {
1911 let sum: u64 = e[..HASH_SELECTOR_BYTES.min(e.len())]
1912 .iter()
1913 .map(|&b| b as u64)
1914 .sum();
1915 (sum % 3) as u8
1916 };
1917
1918 k = match hash_selector {
1919 0 => sha256(&e),
1920 1 => sha384(&e),
1921 2 => sha512(&e),
1922 _ => unreachable!("Modulo 3 can only be 0, 1, or 2"),
1923 };
1924
1925 let last_byte = *e.last().unwrap_or(&0);
1928 round += 1;
1929
1930 if round >= ALGORITHM_2B_MIN_ROUNDS {
1931 if (last_byte as usize) <= round.saturating_sub(32) {
1935 break;
1936 }
1937 }
1938
1939 if round >= ALGORITHM_2B_MAX_ROUNDS {
1941 break;
1942 }
1943 }
1944
1945 Ok(k[..32.min(k.len())].to_vec())
1948}
1949
1950const R5_SALT_LENGTH: usize = 8;
1952
1953const R5_HASH_ITERATIONS: usize = 0;
1957
1958const R6_SALT_LENGTH: usize = 8;
1960
1961const U_HASH_LENGTH: usize = 32;
1967
1968const U_VALIDATION_SALT_START: usize = 32;
1970
1971const U_VALIDATION_SALT_END: usize = 40;
1973
1974const U_KEY_SALT_START: usize = 40;
1976
1977const U_KEY_SALT_END: usize = 48;
1979
1980const U_ENTRY_LENGTH: usize = 48;
1982
1983const UE_ENTRY_LENGTH: usize = 32;
1985
1986const PERMS_ENTRY_LENGTH: usize = 16;
1992
1993const PERMS_P_START: usize = 0;
1995
1996const PERMS_P_END: usize = 4;
1998
1999const PERMS_MARKER_START: usize = 4;
2001
2002const PERMS_MARKER_END: usize = 8;
2004
2005const PERMS_LITERAL_START: usize = 8;
2007
2008const PERMS_LITERAL_END: usize = 11;
2010
2011const PERMS_ENCRYPT_META_BYTE: usize = 11;
2013
2014const PERMS_MARKER: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];
2016
2017const PERMS_LITERAL: &[u8; 3] = b"adb";
2019
2020fn generate_salt(len: usize) -> Vec<u8> {
2030 let mut salt = vec![0u8; len];
2031 rand::rng().fill_bytes(&mut salt);
2032 salt
2033}
2034
2035#[cfg(test)]
2036mod tests {
2037 use super::*;
2038
2039 #[test]
2040 fn test_pad_password() {
2041 let padded = StandardSecurityHandler::pad_password("test");
2042 assert_eq!(padded.len(), 32);
2043 assert_eq!(&padded[..4], b"test");
2044 assert_eq!(&padded[4..8], &PADDING[..4]);
2045 }
2046
2047 #[test]
2048 fn test_pad_password_long() {
2049 let long_password = "a".repeat(40);
2050 let padded = StandardSecurityHandler::pad_password(&long_password);
2051 assert_eq!(padded.len(), 32);
2052 assert_eq!(&padded[..32], &long_password.as_bytes()[..32]);
2053 }
2054
2055 #[test]
2056 fn test_rc4_40bit_handler() {
2057 let handler = StandardSecurityHandler::rc4_40bit();
2058 assert_eq!(handler.revision, SecurityHandlerRevision::R2);
2059 assert_eq!(handler.key_length, 5);
2060 }
2061
2062 #[test]
2063 fn test_rc4_128bit_handler() {
2064 let handler = StandardSecurityHandler::rc4_128bit();
2065 assert_eq!(handler.revision, SecurityHandlerRevision::R3);
2066 assert_eq!(handler.key_length, 16);
2067 }
2068
2069 #[test]
2070 fn test_owner_hash_computation() {
2071 let handler = StandardSecurityHandler::rc4_40bit();
2072 let owner_pwd = OwnerPassword("owner".to_string());
2073 let user_pwd = UserPassword("user".to_string());
2074
2075 let hash = handler.compute_owner_hash(&owner_pwd, &user_pwd);
2076 assert_eq!(hash.len(), 32);
2077 }
2078
2079 #[test]
2080 fn test_encryption_key_computation() {
2081 let handler = StandardSecurityHandler::rc4_40bit();
2082 let user_pwd = UserPassword("user".to_string());
2083 let owner_hash = vec![0u8; 32];
2084 let permissions = Permissions::new();
2085
2086 let key = handler
2087 .compute_encryption_key(&user_pwd, &owner_hash, permissions, None)
2088 .unwrap();
2089
2090 assert_eq!(key.len(), 5);
2091 }
2092
2093 #[test]
2094 fn test_aes_256_r5_handler() {
2095 let handler = StandardSecurityHandler::aes_256_r5();
2096 assert_eq!(handler.revision, SecurityHandlerRevision::R5);
2097 assert_eq!(handler.key_length, 32);
2098 }
2099
2100 #[test]
2101 fn test_aes_256_r6_handler() {
2102 let handler = StandardSecurityHandler::aes_256_r6();
2103 assert_eq!(handler.revision, SecurityHandlerRevision::R6);
2104 assert_eq!(handler.key_length, 32);
2105 }
2106
2107 #[test]
2108 fn test_aes_encryption_key_computation() {
2109 let handler = StandardSecurityHandler::aes_256_r5();
2110 let user_pwd = UserPassword("testuser".to_string());
2111 let owner_hash = vec![0u8; 32];
2112 let permissions = Permissions::new();
2113
2114 let key = handler
2115 .compute_aes_encryption_key(&user_pwd, &owner_hash, permissions, None)
2116 .unwrap();
2117
2118 assert_eq!(key.len(), 32);
2119 }
2120
2121 #[test]
2122 fn test_aes_encrypt_decrypt() {
2123 let handler = StandardSecurityHandler::aes_256_r5();
2124 let key = EncryptionKey::new(vec![0u8; 32]);
2125 let obj_id = ObjectId::new(1, 0);
2126 let data = b"Hello AES encryption!";
2127
2128 let encrypted = handler.encrypt_aes(data, &key, &obj_id).unwrap();
2129 assert_ne!(encrypted.as_slice(), data);
2130 assert!(encrypted.len() > data.len()); let _decrypted = handler.decrypt_aes(&encrypted, &key, &obj_id);
2134 }
2136
2137 #[test]
2138 fn test_aes_with_rc4_handler_fails() {
2139 let handler = StandardSecurityHandler::rc4_128bit();
2140 let key = EncryptionKey::new(vec![0u8; 16]);
2141 let obj_id = ObjectId::new(1, 0);
2142 let data = b"test data";
2143
2144 assert!(handler.encrypt_aes(data, &key, &obj_id).is_err());
2146 assert!(handler.decrypt_aes(data, &key, &obj_id).is_err());
2147 }
2148
2149 #[test]
2150 fn test_aes_decrypt_invalid_data() {
2151 let handler = StandardSecurityHandler::aes_256_r5();
2152 let key = EncryptionKey::new(vec![0u8; 32]);
2153 let obj_id = ObjectId::new(1, 0);
2154
2155 let short_data = vec![0u8; 10];
2157 assert!(handler.decrypt_aes(&short_data, &key, &obj_id).is_err());
2158 }
2159
2160 #[test]
2161 fn test_sha256_deterministic() {
2162 let data1 = b"test data";
2163 let data2 = b"test data";
2164 let data3 = b"different data";
2165
2166 let hash1 = sha256(data1);
2167 let hash2 = sha256(data2);
2168 let hash3 = sha256(data3);
2169
2170 assert_eq!(hash1.len(), 32);
2171 assert_eq!(hash2.len(), 32);
2172 assert_eq!(hash3.len(), 32);
2173
2174 assert_eq!(hash1, hash2); assert_ne!(hash1, hash3); }
2177
2178 #[test]
2179 fn test_security_handler_revision_ordering() {
2180 assert!(SecurityHandlerRevision::R2 < SecurityHandlerRevision::R3);
2181 assert!(SecurityHandlerRevision::R3 < SecurityHandlerRevision::R4);
2182 assert!(SecurityHandlerRevision::R4 < SecurityHandlerRevision::R5);
2183 assert!(SecurityHandlerRevision::R5 < SecurityHandlerRevision::R6);
2184 }
2185
2186 #[test]
2187 fn test_aes_password_validation() {
2188 let handler = StandardSecurityHandler::aes_256_r5();
2189 let password = UserPassword("testpassword".to_string());
2190 let user_hash = vec![0u8; 32]; let permissions = Permissions::new();
2192
2193 let result = handler.validate_aes_user_password(&password, &user_hash, permissions, None);
2195 assert!(result.is_ok());
2196 }
2197
2198 #[test]
2201 fn test_user_password_debug() {
2202 let pwd = UserPassword("debug_test".to_string());
2203 let debug_str = format!("{pwd:?}");
2204 assert!(debug_str.contains("UserPassword"));
2205 assert!(debug_str.contains("debug_test"));
2206 }
2207
2208 #[test]
2209 fn test_owner_password_debug() {
2210 let pwd = OwnerPassword("owner_debug".to_string());
2211 let debug_str = format!("{pwd:?}");
2212 assert!(debug_str.contains("OwnerPassword"));
2213 assert!(debug_str.contains("owner_debug"));
2214 }
2215
2216 #[test]
2217 fn test_encryption_key_debug() {
2218 let key = EncryptionKey::new(vec![0x01, 0x02, 0x03]);
2219 let debug_str = format!("{key:?}");
2220 assert!(debug_str.contains("EncryptionKey"));
2221 }
2222
2223 #[test]
2224 fn test_security_handler_revision_equality() {
2225 assert_eq!(SecurityHandlerRevision::R2, SecurityHandlerRevision::R2);
2226 assert_ne!(SecurityHandlerRevision::R2, SecurityHandlerRevision::R3);
2227 }
2228
2229 #[test]
2230 fn test_security_handler_revision_values() {
2231 assert_eq!(SecurityHandlerRevision::R2 as u8, 2);
2232 assert_eq!(SecurityHandlerRevision::R3 as u8, 3);
2233 assert_eq!(SecurityHandlerRevision::R4 as u8, 4);
2234 assert_eq!(SecurityHandlerRevision::R5 as u8, 5);
2235 assert_eq!(SecurityHandlerRevision::R6 as u8, 6);
2236 }
2237
2238 #[test]
2239 fn test_pad_password_various_lengths() {
2240 for len in 0..=40 {
2241 let password = "x".repeat(len);
2242 let padded = StandardSecurityHandler::pad_password(&password);
2243 assert_eq!(padded.len(), 32);
2244
2245 if len <= 32 {
2246 assert_eq!(&padded[..len], password.as_bytes());
2247 } else {
2248 assert_eq!(&padded[..], &password.as_bytes()[..32]);
2249 }
2250 }
2251 }
2252
2253 #[test]
2254 fn test_pad_password_unicode() {
2255 let padded = StandardSecurityHandler::pad_password("café");
2256 assert_eq!(padded.len(), 32);
2257 assert_eq!(&padded[..5], "café".as_bytes());
2259 }
2260
2261 #[test]
2262 fn test_compute_owner_hash_different_users() {
2263 let handler = StandardSecurityHandler::rc4_128bit();
2264 let owner = OwnerPassword("owner".to_string());
2265 let user1 = UserPassword("user1".to_string());
2266 let user2 = UserPassword("user2".to_string());
2267
2268 let hash1 = handler.compute_owner_hash(&owner, &user1);
2269 let hash2 = handler.compute_owner_hash(&owner, &user2);
2270
2271 assert_ne!(hash1, hash2); }
2273
2274 #[test]
2275 fn test_compute_user_hash_r4() {
2276 let handler = StandardSecurityHandler {
2277 revision: SecurityHandlerRevision::R4,
2278 key_length: 16,
2279 };
2280 let user = UserPassword("r4test".to_string());
2281 let owner_hash = vec![0xAA; 32];
2282 let permissions = Permissions::new();
2283
2284 let hash = handler
2285 .compute_user_hash(&user, &owner_hash, permissions, None)
2286 .unwrap();
2287 assert_eq!(hash.len(), 32);
2288 }
2289
2290 #[test]
2291 fn test_compute_user_hash_r6() {
2292 let handler = StandardSecurityHandler::aes_256_r6();
2293 let user = UserPassword("r6test".to_string());
2294 let owner_hash = vec![0xBB; 32];
2295 let permissions = Permissions::all();
2296
2297 let hash = handler
2298 .compute_user_hash(&user, &owner_hash, permissions, None)
2299 .unwrap();
2300 assert_eq!(hash.len(), 32);
2301 }
2302
2303 #[test]
2304 fn test_encryption_key_with_file_id_affects_result() {
2305 let handler = StandardSecurityHandler::rc4_128bit();
2306 let user = UserPassword("test".to_string());
2307 let owner_hash = vec![0xFF; 32];
2308 let permissions = Permissions::new();
2309 let file_id = b"unique_file_id_12345";
2310
2311 let key_with_id = handler
2312 .compute_encryption_key(&user, &owner_hash, permissions, Some(file_id))
2313 .unwrap();
2314 let key_without_id = handler
2315 .compute_encryption_key(&user, &owner_hash, permissions, None)
2316 .unwrap();
2317
2318 assert_ne!(key_with_id.key, key_without_id.key);
2319 }
2320
2321 #[test]
2322 fn test_encrypt_string_empty() {
2323 let handler = StandardSecurityHandler::rc4_40bit();
2324 let key = EncryptionKey::new(vec![0x01, 0x02, 0x03, 0x04, 0x05]);
2325 let obj_id = ObjectId::new(1, 0);
2326
2327 let encrypted = handler.encrypt_string(b"", &key, &obj_id);
2328 assert_eq!(encrypted.len(), 0);
2329 }
2330
2331 #[test]
2332 fn test_encrypt_decrypt_large_data() {
2333 let handler = StandardSecurityHandler::rc4_128bit();
2334 let key = EncryptionKey::new(vec![0xAA; 16]);
2335 let obj_id = ObjectId::new(42, 0);
2336 let large_data = vec![0x55; 10000]; let encrypted = handler.encrypt_string(&large_data, &key, &obj_id);
2339 assert_eq!(encrypted.len(), large_data.len());
2340 assert_ne!(encrypted, large_data);
2341
2342 let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id);
2343 assert_eq!(decrypted, large_data);
2344 }
2345
2346 #[test]
2347 fn test_stream_encryption_different_from_string() {
2348 let handler = StandardSecurityHandler::rc4_128bit();
2350 let key = EncryptionKey::new(vec![0x11; 16]);
2351 let obj_id = ObjectId::new(5, 1);
2352 let data = b"Stream content test";
2353
2354 let encrypted_string = handler.encrypt_string(data, &key, &obj_id);
2355 let encrypted_stream = handler.encrypt_stream(data, &key, &obj_id);
2356
2357 assert_eq!(encrypted_string, encrypted_stream); }
2359
2360 #[test]
2361 fn test_aes_encryption_with_different_object_ids() {
2362 let handler = StandardSecurityHandler::aes_256_r5();
2363 let key = EncryptionKey::new(vec![0x77; 32]);
2364 let obj_id1 = ObjectId::new(10, 0);
2365 let obj_id2 = ObjectId::new(11, 0);
2366 let data = b"AES test data";
2367
2368 let encrypted1 = handler.encrypt_aes(data, &key, &obj_id1).unwrap();
2369 let encrypted2 = handler.encrypt_aes(data, &key, &obj_id2).unwrap();
2370
2371 assert_ne!(encrypted1, encrypted2);
2373 }
2374
2375 #[test]
2376 fn test_aes_decrypt_invalid_iv_length() {
2377 let handler = StandardSecurityHandler::aes_256_r5();
2378 let key = EncryptionKey::new(vec![0x88; 32]);
2379 let obj_id = ObjectId::new(1, 0);
2380
2381 let short_data = vec![0u8; 10];
2383 assert!(handler.decrypt_aes(&short_data, &key, &obj_id).is_err());
2384
2385 let iv_only = vec![0u8; 16];
2387 let result = handler.decrypt_aes(&iv_only, &key, &obj_id);
2388 if let Ok(decrypted) = result {
2390 assert_eq!(decrypted.len(), 0);
2391 }
2392 }
2393
2394 #[test]
2395 fn test_aes_validate_password_wrong_hash_length() {
2396 let handler = StandardSecurityHandler::aes_256_r5();
2397 let password = UserPassword("test".to_string());
2398 let short_hash = vec![0u8; 16]; let permissions = Permissions::new();
2400
2401 let result = handler
2402 .validate_aes_user_password(&password, &short_hash, permissions, None)
2403 .unwrap();
2404 assert!(!result); }
2406
2407 #[test]
2408 fn test_permissions_affect_encryption_key() {
2409 let handler = StandardSecurityHandler::rc4_128bit();
2410 let user = UserPassword("same_user".to_string());
2411 let owner_hash = vec![0xCC; 32];
2412
2413 let perms1 = Permissions::new();
2414 let perms2 = Permissions::all();
2415
2416 let key1 = handler
2417 .compute_encryption_key(&user, &owner_hash, perms1, None)
2418 .unwrap();
2419 let key2 = handler
2420 .compute_encryption_key(&user, &owner_hash, perms2, None)
2421 .unwrap();
2422
2423 assert_ne!(key1.key, key2.key); }
2425
2426 #[test]
2427 fn test_different_handlers_produce_different_keys() {
2428 let user = UserPassword("test".to_string());
2429 let owner_hash = vec![0xDD; 32];
2430 let permissions = Permissions::new();
2431
2432 let handler_r2 = StandardSecurityHandler::rc4_40bit();
2433 let handler_r3 = StandardSecurityHandler::rc4_128bit();
2434
2435 let key_r2 = handler_r2
2436 .compute_encryption_key(&user, &owner_hash, permissions, None)
2437 .unwrap();
2438 let key_r3 = handler_r3
2439 .compute_encryption_key(&user, &owner_hash, permissions, None)
2440 .unwrap();
2441
2442 assert_ne!(key_r2.len(), key_r3.len()); assert_eq!(key_r2.len(), 5);
2444 assert_eq!(key_r3.len(), 16);
2445 }
2446
2447 #[test]
2448 fn test_full_workflow_aes_r6() {
2449 let handler = StandardSecurityHandler::aes_256_r6();
2450 let user_pwd = UserPassword("user_r6".to_string());
2451 let permissions = Permissions::new();
2452 let file_id = b"test_file_r6";
2453
2454 let owner_hash = vec![0x42; 32]; let user_hash = handler
2459 .compute_user_hash(&user_pwd, &owner_hash, permissions, Some(file_id))
2460 .unwrap();
2461 assert_eq!(user_hash.len(), 32);
2462
2463 let key = handler
2465 .compute_aes_encryption_key(&user_pwd, &owner_hash, permissions, Some(file_id))
2466 .unwrap();
2467 assert_eq!(key.len(), 32);
2468
2469 let obj_id = ObjectId::new(100, 5);
2471 let content = b"R6 AES encryption test";
2472 let encrypted = handler.encrypt_string(content, &key, &obj_id);
2473
2474 if !encrypted.is_empty() {
2476 assert_ne!(encrypted.as_slice(), content);
2477 }
2478 }
2479
2480 #[test]
2481 fn test_md5_compute_consistency() {
2482 let data = b"consistent data for md5";
2483 let hash1 = md5::compute(data);
2484 let hash2 = md5::compute(data);
2485
2486 assert_eq!(hash1, hash2);
2487 assert_eq!(hash1.len(), 16);
2488 }
2489
2490 #[test]
2491 fn test_sha256_consistency() {
2492 let data = b"consistent data for sha256";
2493 let hash1 = sha256(data);
2494 let hash2 = sha256(data);
2495
2496 assert_eq!(hash1, hash2);
2497 assert_eq!(hash1.len(), 32);
2498 }
2499
2500 #[test]
2501 fn test_rc4_encrypt_helper() {
2502 let key = Rc4Key::from_slice(&[0x01, 0x02, 0x03, 0x04, 0x05]);
2503 let data = b"test rc4 helper";
2504
2505 let encrypted = rc4_encrypt(&key, data);
2506 assert_ne!(encrypted.as_slice(), data);
2507
2508 let decrypted = rc4_encrypt(&key, &encrypted);
2510 assert_eq!(decrypted.as_slice(), data);
2511 }
2512
2513 #[test]
2514 fn test_edge_case_max_object_generation() {
2515 let handler = StandardSecurityHandler::rc4_128bit();
2516 let key = EncryptionKey::new(vec![0xEE; 16]);
2517 let obj_id = ObjectId::new(0xFFFFFF, 0xFFFF); let data = b"edge case";
2519
2520 let encrypted = handler.encrypt_string(data, &key, &obj_id);
2521 let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id);
2522 assert_eq!(decrypted.as_slice(), data);
2523 }
2524
2525 #[test]
2530 fn test_try_decrypt_stream_surfaces_aes_error() {
2531 let handler = StandardSecurityHandler::aes_128_r4();
2532 let key = EncryptionKey::new(vec![0x11; 16]);
2533 let obj_id = ObjectId::new(1, 0);
2534
2535 let undecryptable = [0u8; 8];
2537
2538 let err = handler.try_decrypt_stream(&undecryptable, &key, &obj_id);
2539 assert!(
2540 err.is_err(),
2541 "try_decrypt_stream must return Err on undecryptable AES data, got {err:?}"
2542 );
2543
2544 let lenient = handler.decrypt_stream(&undecryptable, &key, &obj_id);
2547 assert!(lenient.is_empty());
2548 }
2549
2550 #[test]
2551 fn test_try_decrypt_string_surfaces_aes_error() {
2552 let handler = StandardSecurityHandler::aes_128_r4();
2553 let key = EncryptionKey::new(vec![0x22; 16]);
2554 let obj_id = ObjectId::new(2, 0);
2555
2556 let undecryptable = [0u8; 4];
2557 assert!(
2558 handler
2559 .try_decrypt_string(&undecryptable, &key, &obj_id)
2560 .is_err(),
2561 "try_decrypt_string must return Err on undecryptable AES data"
2562 );
2563 }
2564
2565 #[test]
2568 fn test_sha256_nist_empty_string() {
2569 let hash = sha256(b"");
2571 let expected: [u8; 32] = [
2572 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f,
2573 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
2574 0x78, 0x52, 0xb8, 0x55,
2575 ];
2576 assert_eq!(
2577 hash.as_slice(),
2578 expected.as_slice(),
2579 "SHA-256('') must match NIST test vector"
2580 );
2581 }
2582
2583 #[test]
2584 fn test_sha256_nist_abc() {
2585 let hash = sha256(b"abc");
2587 let expected: [u8; 32] = [
2588 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
2589 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
2590 0xf2, 0x00, 0x15, 0xad,
2591 ];
2592 assert_eq!(
2593 hash.as_slice(),
2594 expected.as_slice(),
2595 "SHA-256('abc') must match NIST test vector"
2596 );
2597 }
2598
2599 #[test]
2600 fn test_sha512_nist_abc() {
2601 let hash = sha512(b"abc");
2603 let expected: [u8; 64] = [
2604 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20,
2605 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6,
2606 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba,
2607 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
2608 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
2609 ];
2610 assert_eq!(
2611 hash.as_slice(),
2612 expected.as_slice(),
2613 "SHA-512('abc') must match NIST test vector"
2614 );
2615 }
2616
2617 #[test]
2618 fn test_sha512_length() {
2619 let hash = sha512(b"test data");
2620 assert_eq!(hash.len(), 64, "SHA-512 must produce 64 bytes");
2621 }
2622
2623 #[test]
2624 fn test_sha512_deterministic() {
2625 let data1 = b"sha512 test data";
2626 let data2 = b"sha512 test data";
2627 let data3 = b"different data";
2628
2629 let hash1 = sha512(data1);
2630 let hash2 = sha512(data2);
2631 let hash3 = sha512(data3);
2632
2633 assert_eq!(hash1, hash2, "Same input must produce same SHA-512 hash");
2634 assert_ne!(hash1, hash3, "Different input must produce different hash");
2635 }
2636
2637 #[test]
2640 fn test_r5_user_hash_computation() {
2641 let handler = StandardSecurityHandler::aes_256_r5();
2642 let password = UserPassword("test_password".to_string());
2643
2644 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2645
2646 assert_eq!(u_entry.len(), 48, "R5 U entry must be 48 bytes");
2648 }
2649
2650 #[test]
2651 fn test_r5_user_password_validation_correct() {
2652 let handler = StandardSecurityHandler::aes_256_r5();
2653 let password = UserPassword("correct_password".to_string());
2654
2655 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2657
2658 let is_valid = handler
2660 .validate_r5_user_password(&password, &u_entry)
2661 .unwrap();
2662 assert!(is_valid, "Correct password must validate");
2663 }
2664
2665 #[test]
2666 fn test_r5_user_password_validation_incorrect() {
2667 let handler = StandardSecurityHandler::aes_256_r5();
2668 let correct_password = UserPassword("correct_password".to_string());
2669 let wrong_password = UserPassword("wrong_password".to_string());
2670
2671 let u_entry = handler.compute_r5_user_hash(&correct_password).unwrap();
2673
2674 let is_valid = handler
2676 .validate_r5_user_password(&wrong_password, &u_entry)
2677 .unwrap();
2678 assert!(!is_valid, "Wrong password must not validate");
2679 }
2680
2681 #[test]
2682 fn test_r5_user_hash_random_salts() {
2683 let handler = StandardSecurityHandler::aes_256_r5();
2684 let password = UserPassword("same_password".to_string());
2685
2686 let u_entry1 = handler.compute_r5_user_hash(&password).unwrap();
2688 let u_entry2 = handler.compute_r5_user_hash(&password).unwrap();
2689
2690 assert_ne!(
2692 &u_entry1[..32],
2693 &u_entry2[..32],
2694 "Different random salts should produce different hashes"
2695 );
2696
2697 assert_ne!(
2699 &u_entry1[32..40],
2700 &u_entry2[32..40],
2701 "Validation salts must be random"
2702 );
2703
2704 assert!(handler
2706 .validate_r5_user_password(&password, &u_entry1)
2707 .unwrap());
2708 assert!(handler
2709 .validate_r5_user_password(&password, &u_entry2)
2710 .unwrap());
2711 }
2712
2713 #[test]
2714 fn test_r5_user_hash_invalid_entry_length() {
2715 let handler = StandardSecurityHandler::aes_256_r5();
2716 let password = UserPassword("test".to_string());
2717
2718 let short_entry = vec![0u8; 32]; let result = handler.validate_r5_user_password(&password, &short_entry);
2721 assert!(result.is_err(), "Short U entry must fail");
2722
2723 let long_entry = vec![0u8; 64]; let result = handler.validate_r5_user_password(&password, &long_entry);
2725 assert!(result.is_err(), "Long U entry must fail");
2726 }
2727
2728 #[test]
2729 fn test_r5_empty_password() {
2730 let handler = StandardSecurityHandler::aes_256_r5();
2731 let empty_password = UserPassword("".to_string());
2732
2733 let u_entry = handler.compute_r5_user_hash(&empty_password).unwrap();
2735 assert_eq!(u_entry.len(), 48);
2736
2737 let is_valid = handler
2738 .validate_r5_user_password(&empty_password, &u_entry)
2739 .unwrap();
2740 assert!(is_valid, "Empty password must validate correctly");
2741
2742 let non_empty = UserPassword("not_empty".to_string());
2744 let is_valid = handler
2745 .validate_r5_user_password(&non_empty, &u_entry)
2746 .unwrap();
2747 assert!(!is_valid, "Non-empty password must not validate");
2748 }
2749
2750 #[test]
2753 fn test_r5_ue_entry_computation() {
2754 let handler = StandardSecurityHandler::aes_256_r5();
2755 let password = UserPassword("ue_test_password".to_string());
2756 let encryption_key = EncryptionKey::new(vec![0xAB; 32]);
2757
2758 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2760
2761 let ue_entry = handler
2763 .compute_r5_ue_entry(&password, &u_entry, &encryption_key)
2764 .unwrap();
2765
2766 assert_eq!(ue_entry.len(), 32, "R5 UE entry must be 32 bytes");
2768
2769 assert_ne!(
2771 ue_entry.as_slice(),
2772 encryption_key.as_bytes(),
2773 "UE must be encrypted"
2774 );
2775 }
2776
2777 #[test]
2778 fn test_r5_encryption_key_recovery() {
2779 let handler = StandardSecurityHandler::aes_256_r5();
2780 let password = UserPassword("recovery_test".to_string());
2781 let original_key = EncryptionKey::new(vec![0x42; 32]);
2782
2783 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2785
2786 let ue_entry = handler
2788 .compute_r5_ue_entry(&password, &u_entry, &original_key)
2789 .unwrap();
2790
2791 let recovered_key = handler
2793 .recover_r5_encryption_key(&password, &u_entry, &ue_entry)
2794 .unwrap();
2795
2796 assert_eq!(
2798 recovered_key.as_bytes(),
2799 original_key.as_bytes(),
2800 "Recovered key must match original"
2801 );
2802 }
2803
2804 #[test]
2805 fn test_r5_ue_wrong_password_fails() {
2806 let handler = StandardSecurityHandler::aes_256_r5();
2807 let correct_password = UserPassword("correct".to_string());
2808 let wrong_password = UserPassword("wrong".to_string());
2809 let original_key = EncryptionKey::new(vec![0x99; 32]);
2810
2811 let u_entry = handler.compute_r5_user_hash(&correct_password).unwrap();
2813 let ue_entry = handler
2814 .compute_r5_ue_entry(&correct_password, &u_entry, &original_key)
2815 .unwrap();
2816
2817 let recovered_key = handler
2819 .recover_r5_encryption_key(&wrong_password, &u_entry, &ue_entry)
2820 .unwrap();
2821
2822 assert_ne!(
2824 recovered_key.as_bytes(),
2825 original_key.as_bytes(),
2826 "Wrong password must produce wrong key"
2827 );
2828 }
2829
2830 #[test]
2831 fn test_r5_ue_invalid_length() {
2832 let handler = StandardSecurityHandler::aes_256_r5();
2833 let password = UserPassword("test".to_string());
2834 let u_entry = vec![0u8; 48]; let short_ue = vec![0u8; 16]; let result = handler.recover_r5_encryption_key(&password, &u_entry, &short_ue);
2839 assert!(result.is_err(), "Short UE entry must fail");
2840
2841 let long_ue = vec![0u8; 64]; let result = handler.recover_r5_encryption_key(&password, &u_entry, &long_ue);
2843 assert!(result.is_err(), "Long UE entry must fail");
2844 }
2845
2846 #[test]
2847 fn test_r5_ue_invalid_u_length() {
2848 let handler = StandardSecurityHandler::aes_256_r5();
2849 let password = UserPassword("test".to_string());
2850 let encryption_key = EncryptionKey::new(vec![0x11; 32]);
2851
2852 let short_u = vec![0u8; 32]; let result = handler.compute_r5_ue_entry(&password, &short_u, &encryption_key);
2855 assert!(
2856 result.is_err(),
2857 "Short U entry must fail for UE computation"
2858 );
2859 }
2860
2861 #[test]
2862 fn test_r5_full_workflow_u_ue() {
2863 let handler = StandardSecurityHandler::aes_256_r5();
2864 let password = UserPassword("full_workflow_test".to_string());
2865 let encryption_key = EncryptionKey::new((0..32).collect::<Vec<u8>>());
2866
2867 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2869 assert_eq!(u_entry.len(), 48);
2870
2871 assert!(handler
2873 .validate_r5_user_password(&password, &u_entry)
2874 .unwrap());
2875
2876 let ue_entry = handler
2878 .compute_r5_ue_entry(&password, &u_entry, &encryption_key)
2879 .unwrap();
2880 assert_eq!(ue_entry.len(), 32);
2881
2882 let recovered = handler
2884 .recover_r5_encryption_key(&password, &u_entry, &ue_entry)
2885 .unwrap();
2886
2887 assert_eq!(
2889 recovered.as_bytes(),
2890 encryption_key.as_bytes(),
2891 "Full R5 workflow: recovered key must match original"
2892 );
2893 }
2894
2895 #[test]
2898 fn test_r6_user_hash_computation() {
2899 let handler = StandardSecurityHandler::aes_256_r6();
2900 let password = UserPassword("r6_test_password".to_string());
2901
2902 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2903
2904 assert_eq!(u_entry.len(), 48, "R6 U entry must be 48 bytes");
2906 }
2907
2908 #[test]
2909 fn test_r6_user_password_validation_correct() {
2910 let handler = StandardSecurityHandler::aes_256_r6();
2911 let password = UserPassword("r6_correct_password".to_string());
2912
2913 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2915
2916 let is_valid = handler
2918 .validate_r6_user_password(&password, &u_entry)
2919 .unwrap();
2920 assert!(is_valid, "Correct R6 password must validate");
2921 }
2922
2923 #[test]
2924 fn test_r6_user_password_validation_incorrect() {
2925 let handler = StandardSecurityHandler::aes_256_r6();
2926 let correct_password = UserPassword("r6_correct".to_string());
2927 let wrong_password = UserPassword("r6_wrong".to_string());
2928
2929 let u_entry = handler.compute_r6_user_hash(&correct_password).unwrap();
2931
2932 let is_valid = handler
2934 .validate_r6_user_password(&wrong_password, &u_entry)
2935 .unwrap();
2936 assert!(!is_valid, "Wrong R6 password must not validate");
2937 }
2938
2939 #[test]
2940 fn test_r6_uses_sha512_not_sha256() {
2941 let handler_r5 = StandardSecurityHandler::aes_256_r5();
2943 let handler_r6 = StandardSecurityHandler::aes_256_r6();
2944 let password = UserPassword("same_password_both_revisions".to_string());
2945
2946 let u_r5 = handler_r5.compute_r5_user_hash(&password).unwrap();
2947 let u_r6 = handler_r6.compute_r6_user_hash(&password).unwrap();
2948
2949 assert_ne!(
2952 &u_r5[..32],
2953 &u_r6[..32],
2954 "R5 (SHA-256) and R6 (SHA-512) must produce different hashes"
2955 );
2956 }
2957
2958 #[test]
2959 fn test_r6_unicode_password() {
2960 let handler = StandardSecurityHandler::aes_256_r6();
2961 let unicode_password = UserPassword("café🔒日本語".to_string());
2962
2963 let u_entry = handler.compute_r6_user_hash(&unicode_password).unwrap();
2964 assert_eq!(u_entry.len(), 48);
2965
2966 let is_valid = handler
2968 .validate_r6_user_password(&unicode_password, &u_entry)
2969 .unwrap();
2970 assert!(is_valid, "Unicode password must validate");
2971
2972 let different_unicode = UserPassword("café🔓日本語".to_string()); let is_valid = handler
2975 .validate_r6_user_password(&different_unicode, &u_entry)
2976 .unwrap();
2977 assert!(!is_valid, "Different Unicode password must not validate");
2978 }
2979
2980 #[test]
2983 fn test_r6_ue_entry_computation() {
2984 let handler = StandardSecurityHandler::aes_256_r6();
2985 let password = UserPassword("r6_ue_test".to_string());
2986 let encryption_key = EncryptionKey::new(vec![0xCD; 32]);
2987
2988 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2989 let ue_entry = handler
2990 .compute_r6_ue_entry(&password, &u_entry, &encryption_key)
2991 .unwrap();
2992
2993 assert_eq!(ue_entry.len(), 32, "R6 UE entry must be 32 bytes");
2994 }
2995
2996 #[test]
2997 fn test_r6_encryption_key_recovery() {
2998 let handler = StandardSecurityHandler::aes_256_r6();
2999 let password = UserPassword("r6_recovery_test".to_string());
3000 let original_key = EncryptionKey::new(vec![0xEF; 32]);
3001
3002 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
3003 let ue_entry = handler
3004 .compute_r6_ue_entry(&password, &u_entry, &original_key)
3005 .unwrap();
3006
3007 let recovered_key = handler
3008 .recover_r6_encryption_key(&password, &u_entry, &ue_entry)
3009 .unwrap();
3010
3011 assert_eq!(
3012 recovered_key.as_bytes(),
3013 original_key.as_bytes(),
3014 "R6: Recovered key must match original"
3015 );
3016 }
3017
3018 #[test]
3021 fn test_r6_perms_entry_computation() {
3022 let handler = StandardSecurityHandler::aes_256_r6();
3023 let permissions = Permissions::all();
3024 let key = EncryptionKey::new(vec![0x42; 32]);
3025
3026 let perms = handler
3027 .compute_r6_perms_entry(permissions, &key, true)
3028 .unwrap();
3029
3030 assert_eq!(perms.len(), 16, "Perms entry must be 16 bytes");
3031 }
3032
3033 #[test]
3034 fn test_r6_perms_validation() {
3035 let handler = StandardSecurityHandler::aes_256_r6();
3036 let permissions = Permissions::new();
3037 let key = EncryptionKey::new(vec![0x55; 32]);
3038
3039 let perms = handler
3040 .compute_r6_perms_entry(permissions, &key, false)
3041 .unwrap();
3042
3043 let is_valid = handler
3044 .validate_r6_perms(&perms, &key, permissions)
3045 .unwrap();
3046 assert!(is_valid, "Perms validation must succeed with correct key");
3047 }
3048
3049 #[test]
3050 fn test_r6_perms_wrong_key_fails() {
3051 let handler = StandardSecurityHandler::aes_256_r6();
3052 let permissions = Permissions::all();
3053 let correct_key = EncryptionKey::new(vec![0xAA; 32]);
3054 let wrong_key = EncryptionKey::new(vec![0xBB; 32]);
3055
3056 let perms = handler
3057 .compute_r6_perms_entry(permissions, &correct_key, true)
3058 .unwrap();
3059
3060 let result = handler.validate_r6_perms(&perms, &wrong_key, permissions);
3062 assert!(result.is_ok()); assert!(!result.unwrap()); }
3065
3066 #[test]
3067 fn test_r6_perms_encrypt_metadata_flag() {
3068 let handler = StandardSecurityHandler::aes_256_r6();
3069 let permissions = Permissions::new();
3070 let key = EncryptionKey::new(vec![0x33; 32]);
3071
3072 let perms_true = handler
3073 .compute_r6_perms_entry(permissions, &key, true)
3074 .unwrap();
3075 let perms_false = handler
3076 .compute_r6_perms_entry(permissions, &key, false)
3077 .unwrap();
3078
3079 assert_ne!(
3081 perms_true, perms_false,
3082 "Different EncryptMetadata must produce different Perms"
3083 );
3084
3085 let flag_true = handler
3087 .extract_r6_encrypt_metadata(&perms_true, &key)
3088 .unwrap();
3089 assert_eq!(flag_true, Some(true));
3090
3091 let flag_false = handler
3092 .extract_r6_encrypt_metadata(&perms_false, &key)
3093 .unwrap();
3094 assert_eq!(flag_false, Some(false));
3095 }
3096
3097 #[test]
3098 fn test_r6_perms_invalid_length() {
3099 let handler = StandardSecurityHandler::aes_256_r6();
3100 let key = EncryptionKey::new(vec![0x44; 32]);
3101 let permissions = Permissions::new();
3102
3103 let invalid_perms = vec![0u8; 12]; let result = handler.validate_r6_perms(&invalid_perms, &key, permissions);
3105 assert!(result.is_err(), "Short Perms entry must fail");
3106 }
3107
3108 #[test]
3109 fn test_r6_full_workflow_with_perms() {
3110 let handler = StandardSecurityHandler::aes_256_r6();
3112 let password = UserPassword("r6_full_workflow".to_string());
3113 let permissions = Permissions::all();
3114 let encryption_key = EncryptionKey::new((0..32).map(|i| (i * 3) as u8).collect());
3115
3116 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
3118 assert_eq!(u_entry.len(), 48);
3119
3120 assert!(handler
3122 .validate_r6_user_password(&password, &u_entry)
3123 .unwrap());
3124
3125 let ue_entry = handler
3127 .compute_r6_ue_entry(&password, &u_entry, &encryption_key)
3128 .unwrap();
3129 assert_eq!(ue_entry.len(), 32);
3130
3131 let perms = handler
3133 .compute_r6_perms_entry(permissions, &encryption_key, true)
3134 .unwrap();
3135 assert_eq!(perms.len(), 16);
3136
3137 let recovered_key = handler
3139 .recover_r6_encryption_key(&password, &u_entry, &ue_entry)
3140 .unwrap();
3141 assert_eq!(
3142 recovered_key.as_bytes(),
3143 encryption_key.as_bytes(),
3144 "Recovered key must match original"
3145 );
3146
3147 let perms_valid = handler
3149 .validate_r6_perms(&perms, &recovered_key, permissions)
3150 .unwrap();
3151 assert!(perms_valid, "Perms must validate with recovered key");
3152
3153 let encrypt_meta = handler
3155 .extract_r6_encrypt_metadata(&perms, &recovered_key)
3156 .unwrap();
3157 assert_eq!(encrypt_meta, Some(true), "EncryptMetadata must be true");
3158 }
3159
3160 #[test]
3163 fn test_r4_aes_object_key_is_16_bytes() {
3164 let handler = StandardSecurityHandler::aes_128_r4();
3165 let key = EncryptionKey::new(vec![0xAB; 16]);
3166 let obj_id = ObjectId::new(7, 0);
3167
3168 let obj_key = handler.compute_r4_aes_object_key(&key, &obj_id);
3169 assert_eq!(obj_key.len(), 16);
3170 }
3171
3172 #[test]
3173 fn test_r4_aes_object_key_includes_salt() {
3174 let handler_r4 = StandardSecurityHandler::aes_128_r4();
3176 let handler_rc4 = StandardSecurityHandler::rc4_128bit();
3177 let key = EncryptionKey::new(vec![0xCD; 16]);
3178 let obj_id = ObjectId::new(3, 0);
3179
3180 let aes_key = handler_r4.compute_r4_aes_object_key(&key, &obj_id);
3181 let rc4_key = handler_rc4.compute_object_key(&key, &obj_id);
3182
3183 assert_ne!(
3184 aes_key, rc4_key,
3185 "AES R4 key must differ from RC4 key due to sAlT"
3186 );
3187 }
3188
3189 #[test]
3190 fn test_r4_aes_object_key_deterministic() {
3191 let handler = StandardSecurityHandler::aes_128_r4();
3192 let key = EncryptionKey::new(vec![0x42; 16]);
3193 let obj_id = ObjectId::new(5, 2);
3194
3195 let key1 = handler.compute_r4_aes_object_key(&key, &obj_id);
3196 let key2 = handler.compute_r4_aes_object_key(&key, &obj_id);
3197 assert_eq!(key1, key2);
3198 }
3199
3200 #[test]
3201 fn test_r4_encrypt_decrypt_roundtrip() {
3202 let handler = StandardSecurityHandler::aes_128_r4();
3203 let key = EncryptionKey::new(vec![0x55; 16]);
3204 let obj_id = ObjectId::new(1, 0);
3205 let plaintext = b"Hello AES-128 R4 encryption!";
3206
3207 let encrypted = handler.encrypt_aes(plaintext, &key, &obj_id).unwrap();
3208 assert_ne!(&encrypted[16..], plaintext.as_slice()); assert!(encrypted.len() > 16); let decrypted = handler.decrypt_aes(&encrypted, &key, &obj_id).unwrap();
3212 assert_eq!(decrypted, plaintext);
3213 }
3214
3215 #[test]
3216 fn test_r4_encrypt_output_has_iv_prefix() {
3217 let handler = StandardSecurityHandler::aes_128_r4();
3218 let key = EncryptionKey::new(vec![0x77; 16]);
3219 let obj_id = ObjectId::new(2, 0);
3220 let data = b"test";
3221
3222 let encrypted = handler.encrypt_aes(data, &key, &obj_id).unwrap();
3223 assert!(encrypted.len() >= 32); assert_eq!((encrypted.len() - 16) % 16, 0);
3226 }
3227
3228 #[test]
3229 fn test_r4_decrypt_rejects_short_data() {
3230 let handler = StandardSecurityHandler::aes_128_r4();
3231 let key = EncryptionKey::new(vec![0x99; 16]);
3232 let obj_id = ObjectId::new(1, 0);
3233
3234 let short = vec![0u8; 10];
3235 assert!(handler.decrypt_aes(&short, &key, &obj_id).is_err());
3236 }
3237
3238 #[test]
3239 fn test_r4_inherent_encrypt_string_uses_aes() {
3240 let handler = StandardSecurityHandler::aes_128_r4();
3242 let key = EncryptionKey::new(vec![0x33; 16]);
3243 let obj_id = ObjectId::new(1, 0);
3244 let data = b"R4 string encryption";
3245
3246 let encrypted = handler.encrypt_string(data, &key, &obj_id);
3247 assert!(encrypted.len() >= 32);
3249
3250 let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id);
3252 assert_eq!(decrypted, data);
3253 }
3254
3255 #[test]
3256 fn test_r4_inherent_stream_uses_aes() {
3257 let handler = StandardSecurityHandler::aes_128_r4();
3258 let key = EncryptionKey::new(vec![0x44; 16]);
3259 let obj_id = ObjectId::new(3, 0);
3260 let data = b"R4 stream content";
3261
3262 let encrypted = handler.encrypt_stream(data, &key, &obj_id);
3263 assert!(encrypted.len() >= 32);
3264
3265 let decrypted = handler.decrypt_stream(&encrypted, &key, &obj_id);
3266 assert_eq!(decrypted, data);
3267 }
3268}