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::RngCore;
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_256_r5() -> Self {
121 Self {
122 revision: SecurityHandlerRevision::R5,
123 key_length: 32,
124 }
125 }
126
127 pub fn aes_256_r6() -> Self {
129 Self {
130 revision: SecurityHandlerRevision::R6,
131 key_length: 32,
132 }
133 }
134
135 fn pad_password(password: &str) -> [u8; 32] {
137 let mut padded = [0u8; 32];
138 let password_bytes = password.as_bytes();
139 let len = password_bytes.len().min(32);
140
141 padded[..len].copy_from_slice(&password_bytes[..len]);
143
144 if len < 32 {
146 padded[len..].copy_from_slice(&PADDING[..32 - len]);
147 }
148
149 padded
150 }
151
152 pub fn compute_owner_hash(
154 &self,
155 owner_password: &OwnerPassword,
156 user_password: &UserPassword,
157 ) -> Vec<u8> {
158 let owner_pad = Self::pad_password(&owner_password.0);
160 let user_pad = Self::pad_password(&user_password.0);
161
162 let mut hash = md5::compute(&owner_pad).to_vec();
164
165 if self.revision >= SecurityHandlerRevision::R3 {
167 for _ in 0..50 {
168 hash = md5::compute(&hash).to_vec();
169 }
170 }
171
172 let rc4_key = Rc4Key::from_slice(&hash[..self.key_length]);
174
175 let mut result = rc4_encrypt(&rc4_key, &user_pad);
177
178 if self.revision >= SecurityHandlerRevision::R3 {
180 for i in 1..=19 {
181 let mut key_bytes = hash[..self.key_length].to_vec();
182 for j in 0..self.key_length {
183 key_bytes[j] ^= i as u8;
184 }
185 let iter_key = Rc4Key::from_slice(&key_bytes);
186 result = rc4_encrypt(&iter_key, &result);
187 }
188 }
189
190 result
191 }
192
193 pub fn compute_user_hash(
195 &self,
196 user_password: &UserPassword,
197 owner_hash: &[u8],
198 permissions: Permissions,
199 file_id: Option<&[u8]>,
200 ) -> Result<Vec<u8>> {
201 let key = self.compute_encryption_key(user_password, owner_hash, permissions, file_id)?;
203
204 match self.revision {
205 SecurityHandlerRevision::R2 => {
206 let rc4_key = Rc4Key::from_slice(&key.key);
208 Ok(rc4_encrypt(&rc4_key, &PADDING))
209 }
210 SecurityHandlerRevision::R3 | SecurityHandlerRevision::R4 => {
211 let mut data = Vec::new();
213 data.extend_from_slice(&PADDING);
214
215 if let Some(id) = file_id {
216 data.extend_from_slice(id);
217 }
218
219 let hash = md5::compute(&data);
220
221 let rc4_key = Rc4Key::from_slice(&key.key);
223 let mut result = rc4_encrypt(&rc4_key, hash.as_ref());
224
225 for i in 1..=19 {
227 let mut key_bytes = key.key.clone();
228 for j in 0..key_bytes.len() {
229 key_bytes[j] ^= i as u8;
230 }
231 let iter_key = Rc4Key::from_slice(&key_bytes);
232 result = rc4_encrypt(&iter_key, &result);
233 }
234
235 result.resize(32, 0);
237 Ok(result)
238 }
239 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
240 let aes_key = self.compute_aes_encryption_key(
242 user_password,
243 owner_hash,
244 permissions,
245 file_id,
246 )?;
247 let hash = sha256(&aes_key.key);
248
249 Ok(hash)
251 }
252 }
253 }
254
255 pub fn compute_encryption_key(
257 &self,
258 user_password: &UserPassword,
259 owner_hash: &[u8],
260 permissions: Permissions,
261 file_id: Option<&[u8]>,
262 ) -> Result<EncryptionKey> {
263 match self.revision {
264 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
265 self.compute_aes_encryption_key(user_password, owner_hash, permissions, file_id)
267 }
268 _ => {
269 let padded = Self::pad_password(&user_password.0);
272
273 let mut data = Vec::new();
275 data.extend_from_slice(&padded);
276 data.extend_from_slice(owner_hash);
277 data.extend_from_slice(&permissions.bits().to_le_bytes());
278
279 if let Some(id) = file_id {
280 data.extend_from_slice(id);
281 }
282
283 #[cfg(debug_assertions)]
284 {
285 eprintln!("[DEBUG compute_key] padded[0..8]: {:02x?}", &padded[..8]);
286 eprintln!("[DEBUG compute_key] owner_hash len: {}", owner_hash.len());
287 eprintln!(
288 "[DEBUG compute_key] P bytes: {:02x?}",
289 permissions.bits().to_le_bytes()
290 );
291 eprintln!("[DEBUG compute_key] data len before MD5: {}", data.len());
292 let data_hex: String = data.iter().map(|b| format!("{:02x}", b)).collect();
294 eprintln!("[DEBUG compute_key] full data hex: {}", data_hex);
295
296 if data_hex == "7573657228bf4e5e4e758a4164004e56fffa01082e2e00b6d0683e802f0ca9fe94e8094419662a774442fb072e3d9f19e9d130ec09a4d0061e78fe920f7ab62ffcffffff9c5b2a0606f918182e6c5cc0cac374d6" {
298 eprintln!("[DEBUG compute_key] DATA MATCHES EXPECTED - should produce eee5568378306e35...");
299 }
300 }
301
302 if self.revision == SecurityHandlerRevision::R4 {
304 }
307
308 let mut hash = md5::compute(&data).to_vec();
310
311 #[cfg(debug_assertions)]
312 {
313 eprintln!(
314 "[DEBUG compute_key] initial hash[0..8]: {:02x?}",
315 &hash[..8]
316 );
317 let hash_hex: String = hash.iter().map(|b| format!("{:02x}", b)).collect();
318 eprintln!("[DEBUG compute_key] full hash: {}", hash_hex);
319 eprintln!("[DEBUG compute_key] key_length: {}", self.key_length);
320 }
321
322 if self.revision >= SecurityHandlerRevision::R3 {
324 for _ in 0..50 {
325 hash = md5::compute(&hash[..self.key_length]).to_vec();
326 }
327 }
328
329 hash.truncate(self.key_length);
331
332 #[cfg(debug_assertions)]
333 {
334 eprintln!("[DEBUG compute_key] final key: {:02x?}", &hash);
335 }
336
337 Ok(EncryptionKey::new(hash))
338 }
339 }
340 }
341
342 pub fn encrypt_string(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
344 match self.revision {
345 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
346 self.encrypt_aes(data, key, obj_id).unwrap_or_default()
348 }
349 _ => {
350 let obj_key = self.compute_object_key(key, obj_id);
352 let rc4_key = Rc4Key::from_slice(&obj_key);
353 rc4_encrypt(&rc4_key, data)
354 }
355 }
356 }
357
358 pub fn decrypt_string(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
360 match self.revision {
361 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
362 self.decrypt_aes(data, key, obj_id).unwrap_or_default()
364 }
365 _ => {
366 self.encrypt_string(data, key, obj_id)
368 }
369 }
370 }
371
372 pub fn encrypt_stream(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
374 self.encrypt_string(data, key, obj_id)
376 }
377
378 pub fn decrypt_stream(&self, data: &[u8], key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
380 match self.revision {
381 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
382 self.decrypt_aes(data, key, obj_id).unwrap_or_default()
384 }
385 _ => {
386 self.decrypt_string(data, key, obj_id)
388 }
389 }
390 }
391
392 pub fn encrypt_aes(
394 &self,
395 data: &[u8],
396 key: &EncryptionKey,
397 obj_id: &ObjectId,
398 ) -> Result<Vec<u8>> {
399 if self.revision < SecurityHandlerRevision::R5 {
400 return Err(crate::error::PdfError::EncryptionError(
401 "AES encryption only supported for Rev 5+".to_string(),
402 ));
403 }
404
405 let obj_key = self.compute_aes_object_key(key, obj_id)?;
406 let aes_key = AesKey::new_256(obj_key)?;
407 let aes = Aes::new(aes_key);
408
409 let iv = generate_iv();
410 let mut result = Vec::new();
411 result.extend_from_slice(&iv);
412
413 let encrypted = aes.encrypt_cbc(data, &iv).map_err(|e| {
414 crate::error::PdfError::EncryptionError(format!("AES encryption failed: {e}"))
415 })?;
416
417 result.extend_from_slice(&encrypted);
418 Ok(result)
419 }
420
421 pub fn decrypt_aes(
423 &self,
424 data: &[u8],
425 key: &EncryptionKey,
426 obj_id: &ObjectId,
427 ) -> Result<Vec<u8>> {
428 if self.revision < SecurityHandlerRevision::R5 {
429 return Err(crate::error::PdfError::EncryptionError(
430 "AES decryption only supported for Rev 5+".to_string(),
431 ));
432 }
433
434 if data.len() < 16 {
435 return Err(crate::error::PdfError::EncryptionError(
436 "AES encrypted data must be at least 16 bytes (IV)".to_string(),
437 ));
438 }
439
440 let iv = &data[0..16];
441 let encrypted_data = &data[16..];
442
443 let obj_key = self.compute_aes_object_key(key, obj_id)?;
444 let aes_key = AesKey::new_256(obj_key)?;
445 let aes = Aes::new(aes_key);
446
447 aes.decrypt_cbc(encrypted_data, iv).map_err(|e| {
448 crate::error::PdfError::EncryptionError(format!("AES decryption failed: {e}"))
449 })
450 }
451
452 fn compute_aes_object_key(&self, key: &EncryptionKey, obj_id: &ObjectId) -> Result<Vec<u8>> {
454 if self.revision < SecurityHandlerRevision::R5 {
455 return Err(crate::error::PdfError::EncryptionError(
456 "AES object key computation only for Rev 5+".to_string(),
457 ));
458 }
459
460 let mut data = Vec::new();
462 data.extend_from_slice(&key.key);
463 data.extend_from_slice(&obj_id.number().to_le_bytes());
464 data.extend_from_slice(&obj_id.generation().to_le_bytes());
465
466 data.extend_from_slice(b"sAlT"); Ok(sha256(&data))
470 }
471
472 pub fn compute_aes_encryption_key(
474 &self,
475 user_password: &UserPassword,
476 owner_hash: &[u8],
477 permissions: Permissions,
478 file_id: Option<&[u8]>,
479 ) -> Result<EncryptionKey> {
480 if self.revision < SecurityHandlerRevision::R5 {
481 return Err(crate::error::PdfError::EncryptionError(
482 "AES key computation only for Rev 5+".to_string(),
483 ));
484 }
485
486 let mut data = Vec::new();
488
489 let password_bytes = user_password.0.as_bytes();
491 data.extend_from_slice(password_bytes);
492
493 data.extend_from_slice(owner_hash);
495 data.extend_from_slice(&permissions.bits().to_le_bytes());
496
497 if let Some(id) = file_id {
498 data.extend_from_slice(id);
499 }
500
501 let mut hash = sha256(&data);
503
504 for _ in 0..100 {
506 hash = sha256(&hash);
507 }
508
509 hash.truncate(32);
511
512 Ok(EncryptionKey::new(hash))
513 }
514
515 pub fn validate_aes_user_password(
517 &self,
518 password: &UserPassword,
519 user_hash: &[u8],
520 permissions: Permissions,
521 file_id: Option<&[u8]>,
522 ) -> Result<bool> {
523 if self.revision < SecurityHandlerRevision::R5 {
524 return Err(crate::error::PdfError::EncryptionError(
525 "AES password validation only for Rev 5+".to_string(),
526 ));
527 }
528
529 let computed_key =
530 self.compute_aes_encryption_key(password, user_hash, permissions, file_id)?;
531
532 let computed_hash = sha256(&computed_key.key);
534
535 Ok(user_hash.len() >= 32 && computed_hash[..32] == user_hash[..32])
536 }
537
538 pub fn compute_r5_user_hash(&self, user_password: &UserPassword) -> Result<Vec<u8>> {
553 if self.revision != SecurityHandlerRevision::R5 {
554 return Err(crate::error::PdfError::EncryptionError(
555 "R5 user hash only for Revision 5".to_string(),
556 ));
557 }
558
559 let validation_salt = generate_salt(R5_SALT_LENGTH);
561 let key_salt = generate_salt(R5_SALT_LENGTH);
562
563 let mut data = Vec::new();
565 data.extend_from_slice(user_password.0.as_bytes());
566 data.extend_from_slice(&validation_salt);
567
568 let mut hash = sha256(&data);
569
570 for _ in 0..R5_HASH_ITERATIONS {
572 hash = sha256(&hash);
573 }
574
575 let mut u_entry = Vec::with_capacity(48);
577 u_entry.extend_from_slice(&hash[..32]);
578 u_entry.extend_from_slice(&validation_salt);
579 u_entry.extend_from_slice(&key_salt);
580
581 debug_assert_eq!(u_entry.len(), 48);
582 Ok(u_entry)
583 }
584
585 pub fn validate_r5_user_password(
599 &self,
600 password: &UserPassword,
601 u_entry: &[u8],
602 ) -> Result<bool> {
603 if u_entry.len() != U_ENTRY_LENGTH {
604 return Err(crate::error::PdfError::EncryptionError(format!(
605 "R5 U entry must be {} bytes, got {}",
606 U_ENTRY_LENGTH,
607 u_entry.len()
608 )));
609 }
610
611 let validation_salt = &u_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
613
614 let mut data = Vec::new();
616 data.extend_from_slice(password.0.as_bytes());
617 data.extend_from_slice(validation_salt);
618
619 let mut hash = sha256(&data);
620
621 for _ in 0..R5_HASH_ITERATIONS {
623 hash = sha256(&hash);
624 }
625
626 let stored_hash = &u_entry[..U_HASH_LENGTH];
628 let computed_hash = &hash[..U_HASH_LENGTH];
629 Ok(bool::from(computed_hash.ct_eq(stored_hash)))
630 }
631
632 pub fn compute_r5_ue_entry(
642 &self,
643 user_password: &UserPassword,
644 u_entry: &[u8],
645 encryption_key: &EncryptionKey,
646 ) -> Result<Vec<u8>> {
647 if u_entry.len() != U_ENTRY_LENGTH {
648 return Err(crate::error::PdfError::EncryptionError(format!(
649 "U entry must be {} bytes",
650 U_ENTRY_LENGTH
651 )));
652 }
653 if encryption_key.len() != UE_ENTRY_LENGTH {
654 return Err(crate::error::PdfError::EncryptionError(format!(
655 "Encryption key must be {} bytes for R5",
656 UE_ENTRY_LENGTH
657 )));
658 }
659
660 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
662
663 let mut data = Vec::new();
665 data.extend_from_slice(user_password.0.as_bytes());
666 data.extend_from_slice(key_salt);
667
668 let intermediate_key = sha256(&data);
669
670 let aes_key = AesKey::new_256(intermediate_key)?;
673 let aes = Aes::new(aes_key);
674 let iv = [0u8; 16];
675
676 let encrypted = aes
677 .encrypt_cbc_raw(encryption_key.as_bytes(), &iv)
678 .map_err(|e| {
679 crate::error::PdfError::EncryptionError(format!("UE encryption failed: {}", e))
680 })?;
681
682 Ok(encrypted)
684 }
685
686 pub fn recover_r5_encryption_key(
693 &self,
694 user_password: &UserPassword,
695 u_entry: &[u8],
696 ue_entry: &[u8],
697 ) -> Result<EncryptionKey> {
698 if ue_entry.len() != UE_ENTRY_LENGTH {
699 return Err(crate::error::PdfError::EncryptionError(format!(
700 "UE entry must be {} bytes, got {}",
701 UE_ENTRY_LENGTH,
702 ue_entry.len()
703 )));
704 }
705 if u_entry.len() != U_ENTRY_LENGTH {
706 return Err(crate::error::PdfError::EncryptionError(format!(
707 "U entry must be {} bytes",
708 U_ENTRY_LENGTH
709 )));
710 }
711
712 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
714
715 let mut data = Vec::new();
717 data.extend_from_slice(user_password.0.as_bytes());
718 data.extend_from_slice(key_salt);
719
720 let intermediate_key = sha256(&data);
721
722 let aes_key = AesKey::new_256(intermediate_key)?;
725 let aes = Aes::new(aes_key);
726 let iv = [0u8; 16];
727
728 let decrypted = aes.decrypt_cbc_raw(ue_entry, &iv).map_err(|e| {
729 crate::error::PdfError::EncryptionError(format!("UE decryption failed: {}", e))
730 })?;
731
732 Ok(EncryptionKey::new(decrypted))
733 }
734
735 pub fn compute_r6_user_hash(&self, user_password: &UserPassword) -> Result<Vec<u8>> {
750 if self.revision != SecurityHandlerRevision::R6 {
751 return Err(crate::error::PdfError::EncryptionError(
752 "R6 user hash only for Revision 6".to_string(),
753 ));
754 }
755
756 let validation_salt = generate_salt(R6_SALT_LENGTH);
758 let key_salt = generate_salt(R6_SALT_LENGTH);
759
760 let hash = compute_hash_r6_algorithm_2b(
763 user_password.0.as_bytes(),
764 &validation_salt,
765 &[], )?;
767
768 let mut u_entry = Vec::with_capacity(48);
770 u_entry.extend_from_slice(&hash[..32]);
771 u_entry.extend_from_slice(&validation_salt);
772 u_entry.extend_from_slice(&key_salt);
773
774 debug_assert_eq!(u_entry.len(), 48);
775 Ok(u_entry)
776 }
777
778 pub fn validate_r6_user_password(
791 &self,
792 password: &UserPassword,
793 u_entry: &[u8],
794 ) -> Result<bool> {
795 if u_entry.len() != U_ENTRY_LENGTH {
796 return Err(crate::error::PdfError::EncryptionError(format!(
797 "R6 U entry must be {} bytes, got {}",
798 U_ENTRY_LENGTH,
799 u_entry.len()
800 )));
801 }
802
803 let validation_salt = &u_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
805
806 let hash = compute_hash_r6_algorithm_2b(password.0.as_bytes(), validation_salt, &[])?;
809
810 let stored_hash = &u_entry[..U_HASH_LENGTH];
812 let computed_hash = &hash[..U_HASH_LENGTH];
813 Ok(bool::from(computed_hash.ct_eq(stored_hash)))
814 }
815
816 pub fn compute_r6_ue_entry(
823 &self,
824 user_password: &UserPassword,
825 u_entry: &[u8],
826 encryption_key: &EncryptionKey,
827 ) -> Result<Vec<u8>> {
828 if u_entry.len() != U_ENTRY_LENGTH {
829 return Err(crate::error::PdfError::EncryptionError(format!(
830 "U entry must be {} bytes",
831 U_ENTRY_LENGTH
832 )));
833 }
834 if encryption_key.len() != UE_ENTRY_LENGTH {
835 return Err(crate::error::PdfError::EncryptionError(format!(
836 "Encryption key must be {} bytes for R6",
837 UE_ENTRY_LENGTH
838 )));
839 }
840
841 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
843
844 let hash = compute_hash_r6_algorithm_2b(user_password.0.as_bytes(), key_salt, u_entry)?;
847 let intermediate_key = hash[..U_HASH_LENGTH].to_vec();
848
849 let aes_key = AesKey::new_256(intermediate_key)?;
851 let aes = Aes::new(aes_key);
852 let iv = [0u8; 16];
853
854 let encrypted = aes
855 .encrypt_cbc_raw(encryption_key.as_bytes(), &iv)
856 .map_err(|e| {
857 crate::error::PdfError::EncryptionError(format!("UE encryption failed: {}", e))
858 })?;
859
860 Ok(encrypted)
861 }
862
863 pub fn recover_r6_encryption_key(
870 &self,
871 user_password: &UserPassword,
872 u_entry: &[u8],
873 ue_entry: &[u8],
874 ) -> Result<EncryptionKey> {
875 if ue_entry.len() != UE_ENTRY_LENGTH {
876 return Err(crate::error::PdfError::EncryptionError(format!(
877 "UE entry must be {} bytes, got {}",
878 UE_ENTRY_LENGTH,
879 ue_entry.len()
880 )));
881 }
882 if u_entry.len() != U_ENTRY_LENGTH {
883 return Err(crate::error::PdfError::EncryptionError(format!(
884 "U entry must be {} bytes",
885 U_ENTRY_LENGTH
886 )));
887 }
888
889 let key_salt = &u_entry[U_KEY_SALT_START..U_KEY_SALT_END];
891
892 let hash = compute_hash_r6_algorithm_2b(user_password.0.as_bytes(), key_salt, u_entry)?;
895 let intermediate_key = hash[..U_HASH_LENGTH].to_vec();
896
897 let aes_key = AesKey::new_256(intermediate_key)?;
899 let aes = Aes::new(aes_key);
900 let iv = [0u8; 16];
901
902 let decrypted = aes.decrypt_cbc_raw(ue_entry, &iv).map_err(|e| {
903 crate::error::PdfError::EncryptionError(format!("UE decryption failed: {}", e))
904 })?;
905
906 Ok(EncryptionKey::new(decrypted))
907 }
908
909 pub fn compute_r6_perms_entry(
925 &self,
926 permissions: Permissions,
927 encryption_key: &EncryptionKey,
928 encrypt_metadata: bool,
929 ) -> Result<Vec<u8>> {
930 if self.revision != SecurityHandlerRevision::R6 {
931 return Err(crate::error::PdfError::EncryptionError(
932 "Perms entry only for Revision 6".to_string(),
933 ));
934 }
935 if encryption_key.len() != UE_ENTRY_LENGTH {
936 return Err(crate::error::PdfError::EncryptionError(format!(
937 "Encryption key must be {} bytes for R6 Perms",
938 UE_ENTRY_LENGTH
939 )));
940 }
941
942 let mut plaintext = vec![0u8; PERMS_ENTRY_LENGTH];
944
945 let p_bytes = (permissions.bits() as u32).to_le_bytes();
947 plaintext[PERMS_P_START..PERMS_P_END].copy_from_slice(&p_bytes);
948
949 plaintext[PERMS_MARKER_START..PERMS_MARKER_END].copy_from_slice(&PERMS_MARKER);
951
952 plaintext[PERMS_LITERAL_START..PERMS_LITERAL_END].copy_from_slice(PERMS_LITERAL);
954
955 plaintext[PERMS_ENCRYPT_META_BYTE] = if encrypt_metadata { b'T' } else { b'F' };
957
958 let aes_key = AesKey::new_256(encryption_key.key.clone())?;
962 let aes = Aes::new(aes_key);
963
964 let encrypted = aes.encrypt_ecb(&plaintext).map_err(|e| {
965 crate::error::PdfError::EncryptionError(format!("Perms encryption failed: {}", e))
966 })?;
967
968 Ok(encrypted)
969 }
970
971 pub fn validate_r6_perms(
981 &self,
982 perms_entry: &[u8],
983 encryption_key: &EncryptionKey,
984 expected_permissions: Permissions,
985 ) -> Result<bool> {
986 if perms_entry.len() != PERMS_ENTRY_LENGTH {
987 return Err(crate::error::PdfError::EncryptionError(format!(
988 "Perms entry must be {} bytes, got {}",
989 PERMS_ENTRY_LENGTH,
990 perms_entry.len()
991 )));
992 }
993 if encryption_key.len() != UE_ENTRY_LENGTH {
994 return Err(crate::error::PdfError::EncryptionError(format!(
995 "Encryption key must be {} bytes",
996 UE_ENTRY_LENGTH
997 )));
998 }
999
1000 let aes_key = AesKey::new_256(encryption_key.key.clone())?;
1002 let aes = Aes::new(aes_key);
1003
1004 let decrypted = aes.decrypt_ecb(perms_entry).map_err(|e| {
1005 crate::error::PdfError::EncryptionError(format!("Perms decryption failed: {}", e))
1006 })?;
1007
1008 if decrypted[PERMS_MARKER_START..PERMS_MARKER_END] != PERMS_MARKER {
1010 return Ok(false);
1011 }
1012
1013 if &decrypted[PERMS_LITERAL_START..PERMS_LITERAL_END] != PERMS_LITERAL {
1015 return Ok(false);
1016 }
1017
1018 let expected_bytes = (expected_permissions.bits() as u32).to_le_bytes();
1020 let actual_bytes = &decrypted[PERMS_P_START..PERMS_P_END];
1021 Ok(bool::from(expected_bytes.ct_eq(actual_bytes)))
1022 }
1023
1024 pub fn extract_r6_encrypt_metadata(
1029 &self,
1030 perms_entry: &[u8],
1031 encryption_key: &EncryptionKey,
1032 ) -> Result<Option<bool>> {
1033 if perms_entry.len() != PERMS_ENTRY_LENGTH || encryption_key.len() != UE_ENTRY_LENGTH {
1034 return Ok(None);
1035 }
1036
1037 let aes_key = AesKey::new_256(encryption_key.key.clone())?;
1038 let aes = Aes::new(aes_key);
1039
1040 let decrypted = match aes.decrypt_ecb(perms_entry) {
1041 Ok(d) => d,
1042 Err(_) => return Ok(None),
1043 };
1044
1045 if decrypted[PERMS_MARKER_START..PERMS_MARKER_END] != PERMS_MARKER
1047 || &decrypted[PERMS_LITERAL_START..PERMS_LITERAL_END] != PERMS_LITERAL
1048 {
1049 return Ok(None);
1050 }
1051
1052 match decrypted[PERMS_ENCRYPT_META_BYTE] {
1054 b'T' => Ok(Some(true)),
1055 b'F' => Ok(Some(false)),
1056 _ => Ok(None), }
1058 }
1059
1060 pub fn compute_r5_owner_hash(
1071 &self,
1072 owner_password: &OwnerPassword,
1073 _user_password: &UserPassword,
1074 ) -> Result<Vec<u8>> {
1075 if self.revision != SecurityHandlerRevision::R5 {
1076 return Err(crate::error::PdfError::EncryptionError(
1077 "R5 owner hash only for Revision 5".to_string(),
1078 ));
1079 }
1080
1081 let validation_salt = generate_salt(R5_SALT_LENGTH);
1083 let key_salt = generate_salt(R5_SALT_LENGTH);
1084
1085 let mut data = Vec::new();
1087 data.extend_from_slice(owner_password.0.as_bytes());
1088 data.extend_from_slice(&validation_salt);
1089
1090 let hash = sha256(&data);
1091
1092 let mut o_entry = Vec::with_capacity(U_ENTRY_LENGTH);
1094 o_entry.extend_from_slice(&hash[..U_HASH_LENGTH]);
1095 o_entry.extend_from_slice(&validation_salt);
1096 o_entry.extend_from_slice(&key_salt);
1097
1098 debug_assert_eq!(o_entry.len(), U_ENTRY_LENGTH);
1099 Ok(o_entry)
1100 }
1101
1102 pub fn validate_r5_owner_password(
1106 &self,
1107 owner_password: &OwnerPassword,
1108 o_entry: &[u8],
1109 ) -> Result<bool> {
1110 if o_entry.len() != U_ENTRY_LENGTH {
1111 return Err(crate::error::PdfError::EncryptionError(format!(
1112 "R5 O entry must be {} bytes, got {}",
1113 U_ENTRY_LENGTH,
1114 o_entry.len()
1115 )));
1116 }
1117
1118 let validation_salt = &o_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
1120
1121 let mut data = Vec::new();
1123 data.extend_from_slice(owner_password.0.as_bytes());
1124 data.extend_from_slice(validation_salt);
1125
1126 let hash = sha256(&data);
1127
1128 let stored_hash = &o_entry[..U_HASH_LENGTH];
1130 Ok(bool::from(hash[..U_HASH_LENGTH].ct_eq(stored_hash)))
1131 }
1132
1133 pub fn compute_r5_oe_entry(
1138 &self,
1139 owner_password: &OwnerPassword,
1140 o_entry: &[u8],
1141 encryption_key: &[u8],
1142 ) -> Result<Vec<u8>> {
1143 if o_entry.len() != U_ENTRY_LENGTH {
1144 return Err(crate::error::PdfError::EncryptionError(format!(
1145 "O entry must be {} bytes",
1146 U_ENTRY_LENGTH
1147 )));
1148 }
1149 if encryption_key.len() != UE_ENTRY_LENGTH {
1150 return Err(crate::error::PdfError::EncryptionError(format!(
1151 "Encryption key must be {} bytes",
1152 UE_ENTRY_LENGTH
1153 )));
1154 }
1155
1156 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1158
1159 let mut data = Vec::new();
1161 data.extend_from_slice(owner_password.0.as_bytes());
1162 data.extend_from_slice(key_salt);
1163
1164 let intermediate_key = sha256(&data);
1165
1166 let aes = Aes::new(AesKey::new_256(intermediate_key)?);
1168 let iv = [0u8; 16];
1169
1170 let encrypted = aes.encrypt_cbc_raw(encryption_key, &iv).map_err(|e| {
1171 crate::error::PdfError::EncryptionError(format!("OE encryption failed: {}", e))
1172 })?;
1173
1174 Ok(encrypted[..UE_ENTRY_LENGTH].to_vec())
1176 }
1177
1178 pub fn recover_r5_owner_encryption_key(
1180 &self,
1181 owner_password: &OwnerPassword,
1182 o_entry: &[u8],
1183 oe_entry: &[u8],
1184 ) -> Result<Vec<u8>> {
1185 if o_entry.len() != U_ENTRY_LENGTH {
1186 return Err(crate::error::PdfError::EncryptionError(format!(
1187 "O entry must be {} bytes",
1188 U_ENTRY_LENGTH
1189 )));
1190 }
1191 if oe_entry.len() != UE_ENTRY_LENGTH {
1192 return Err(crate::error::PdfError::EncryptionError(format!(
1193 "OE entry must be {} bytes",
1194 UE_ENTRY_LENGTH
1195 )));
1196 }
1197
1198 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1200
1201 let mut data = Vec::new();
1203 data.extend_from_slice(owner_password.0.as_bytes());
1204 data.extend_from_slice(key_salt);
1205
1206 let intermediate_key = sha256(&data);
1207
1208 let aes = Aes::new(AesKey::new_256(intermediate_key)?);
1210 let iv = [0u8; 16];
1211
1212 let decrypted = aes.decrypt_cbc_raw(oe_entry, &iv).map_err(|e| {
1213 crate::error::PdfError::EncryptionError(format!("OE decryption failed: {}", e))
1214 })?;
1215
1216 Ok(decrypted)
1217 }
1218
1219 pub fn compute_r6_owner_hash(
1223 &self,
1224 owner_password: &OwnerPassword,
1225 u_entry: &[u8],
1226 ) -> Result<Vec<u8>> {
1227 if self.revision != SecurityHandlerRevision::R6 {
1228 return Err(crate::error::PdfError::EncryptionError(
1229 "R6 owner hash only for Revision 6".to_string(),
1230 ));
1231 }
1232 if u_entry.len() != U_ENTRY_LENGTH {
1233 return Err(crate::error::PdfError::EncryptionError(format!(
1234 "U entry must be {} bytes for R6 O computation",
1235 U_ENTRY_LENGTH
1236 )));
1237 }
1238
1239 let validation_salt = generate_salt(R6_SALT_LENGTH);
1241 let key_salt = generate_salt(R6_SALT_LENGTH);
1242
1243 let mut input = Vec::new();
1245 input.extend_from_slice(owner_password.0.as_bytes());
1246 input.extend_from_slice(&validation_salt);
1247 input.extend_from_slice(u_entry);
1248
1249 let hash = compute_hash_r6_algorithm_2b(&input, owner_password.0.as_bytes(), u_entry)?;
1250
1251 let mut o_entry = Vec::with_capacity(U_ENTRY_LENGTH);
1253 o_entry.extend_from_slice(&hash[..U_HASH_LENGTH]);
1254 o_entry.extend_from_slice(&validation_salt);
1255 o_entry.extend_from_slice(&key_salt);
1256
1257 debug_assert_eq!(o_entry.len(), U_ENTRY_LENGTH);
1258 Ok(o_entry)
1259 }
1260
1261 pub fn validate_r6_owner_password(
1265 &self,
1266 owner_password: &OwnerPassword,
1267 o_entry: &[u8],
1268 u_entry: &[u8],
1269 ) -> Result<bool> {
1270 if o_entry.len() != U_ENTRY_LENGTH {
1271 return Err(crate::error::PdfError::EncryptionError(format!(
1272 "R6 O entry must be {} bytes",
1273 U_ENTRY_LENGTH
1274 )));
1275 }
1276 if u_entry.len() != U_ENTRY_LENGTH {
1277 return Err(crate::error::PdfError::EncryptionError(format!(
1278 "R6 U entry must be {} bytes",
1279 U_ENTRY_LENGTH
1280 )));
1281 }
1282
1283 let validation_salt = &o_entry[U_VALIDATION_SALT_START..U_VALIDATION_SALT_END];
1285
1286 let mut input = Vec::new();
1288 input.extend_from_slice(owner_password.0.as_bytes());
1289 input.extend_from_slice(validation_salt);
1290 input.extend_from_slice(u_entry);
1291
1292 let hash = compute_hash_r6_algorithm_2b(&input, owner_password.0.as_bytes(), u_entry)?;
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_r6_oe_entry(
1303 &self,
1304 owner_password: &OwnerPassword,
1305 o_entry: &[u8],
1306 u_entry: &[u8],
1307 encryption_key: &[u8],
1308 ) -> Result<Vec<u8>> {
1309 if o_entry.len() != U_ENTRY_LENGTH {
1310 return Err(crate::error::PdfError::EncryptionError(format!(
1311 "O entry must be {} bytes",
1312 U_ENTRY_LENGTH
1313 )));
1314 }
1315 if u_entry.len() != U_ENTRY_LENGTH {
1316 return Err(crate::error::PdfError::EncryptionError(format!(
1317 "U entry must be {} bytes",
1318 U_ENTRY_LENGTH
1319 )));
1320 }
1321 if encryption_key.len() != UE_ENTRY_LENGTH {
1322 return Err(crate::error::PdfError::EncryptionError(format!(
1323 "Encryption key must be {} bytes",
1324 UE_ENTRY_LENGTH
1325 )));
1326 }
1327
1328 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1330
1331 let mut input = Vec::new();
1333 input.extend_from_slice(owner_password.0.as_bytes());
1334 input.extend_from_slice(key_salt);
1335 input.extend_from_slice(u_entry);
1336
1337 let intermediate_key =
1338 compute_hash_r6_algorithm_2b(&input, owner_password.0.as_bytes(), u_entry)?;
1339
1340 let aes = Aes::new(AesKey::new_256(intermediate_key[..32].to_vec())?);
1342 let iv = [0u8; 16];
1343
1344 let encrypted = aes.encrypt_cbc_raw(encryption_key, &iv).map_err(|e| {
1345 crate::error::PdfError::EncryptionError(format!("OE encryption failed: {}", e))
1346 })?;
1347
1348 Ok(encrypted[..UE_ENTRY_LENGTH].to_vec())
1349 }
1350
1351 pub fn recover_r6_owner_encryption_key(
1353 &self,
1354 owner_password: &OwnerPassword,
1355 o_entry: &[u8],
1356 u_entry: &[u8],
1357 oe_entry: &[u8],
1358 ) -> Result<Vec<u8>> {
1359 if o_entry.len() != U_ENTRY_LENGTH {
1360 return Err(crate::error::PdfError::EncryptionError(format!(
1361 "O entry must be {} bytes",
1362 U_ENTRY_LENGTH
1363 )));
1364 }
1365 if u_entry.len() != U_ENTRY_LENGTH {
1366 return Err(crate::error::PdfError::EncryptionError(format!(
1367 "U entry must be {} bytes",
1368 U_ENTRY_LENGTH
1369 )));
1370 }
1371 if oe_entry.len() != UE_ENTRY_LENGTH {
1372 return Err(crate::error::PdfError::EncryptionError(format!(
1373 "OE entry must be {} bytes",
1374 UE_ENTRY_LENGTH
1375 )));
1376 }
1377
1378 let key_salt = &o_entry[U_KEY_SALT_START..U_KEY_SALT_END];
1380
1381 let mut input = Vec::new();
1383 input.extend_from_slice(owner_password.0.as_bytes());
1384 input.extend_from_slice(key_salt);
1385 input.extend_from_slice(u_entry);
1386
1387 let intermediate_key =
1388 compute_hash_r6_algorithm_2b(&input, owner_password.0.as_bytes(), u_entry)?;
1389
1390 let aes = Aes::new(AesKey::new_256(intermediate_key[..32].to_vec())?);
1392 let iv = [0u8; 16];
1393
1394 let decrypted = aes.decrypt_cbc_raw(oe_entry, &iv).map_err(|e| {
1395 crate::error::PdfError::EncryptionError(format!("OE decryption failed: {}", e))
1396 })?;
1397
1398 Ok(decrypted)
1399 }
1400
1401 pub fn compute_object_key(&self, key: &EncryptionKey, obj_id: &ObjectId) -> Vec<u8> {
1403 let mut data = Vec::new();
1404 data.extend_from_slice(&key.key);
1405 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);
1409 let key_len = (key.len() + 5).min(16);
1410 hash[..key_len].to_vec()
1411 }
1412
1413 pub fn validate_user_password(
1418 &self,
1419 password: &UserPassword,
1420 user_hash: &[u8],
1421 owner_hash: &[u8],
1422 permissions: Permissions,
1423 file_id: Option<&[u8]>,
1424 ) -> Result<bool> {
1425 let key = self.compute_encryption_key(password, owner_hash, permissions, file_id)?;
1427
1428 match self.revision {
1429 SecurityHandlerRevision::R2 => {
1430 let rc4_key = Rc4Key::from_slice(&key.key);
1432 let encrypted_padding = rc4_encrypt(&rc4_key, &PADDING);
1433
1434 Ok(user_hash.len() >= 32 && encrypted_padding[..] == user_hash[..32])
1436 }
1437 SecurityHandlerRevision::R3 | SecurityHandlerRevision::R4 => {
1438 let mut data = Vec::new();
1440 data.extend_from_slice(&PADDING);
1441
1442 if let Some(id) = file_id {
1443 data.extend_from_slice(id);
1444 }
1445
1446 let hash = md5::compute(&data);
1447
1448 let rc4_key = Rc4Key::from_slice(&key.key);
1450 let mut encrypted = rc4_encrypt(&rc4_key, hash.as_ref());
1451
1452 for i in 1..=19 {
1454 let mut key_bytes = key.key.clone();
1455 for byte in &mut key_bytes {
1456 *byte ^= i as u8;
1457 }
1458 let iter_key = Rc4Key::from_slice(&key_bytes);
1459 encrypted = rc4_encrypt(&iter_key, &encrypted);
1460 }
1461
1462 Ok(user_hash.len() >= 16 && encrypted[..16] == user_hash[..16])
1464 }
1465 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
1466 self.validate_aes_user_password(password, user_hash, permissions, file_id)
1468 }
1469 }
1470 }
1471
1472 pub fn validate_owner_password(
1480 &self,
1481 owner_password: &OwnerPassword,
1482 owner_hash: &[u8],
1483 _user_password: &UserPassword, _permissions: Permissions,
1485 _file_id: Option<&[u8]>,
1486 ) -> Result<bool> {
1487 match self.revision {
1488 SecurityHandlerRevision::R2
1489 | SecurityHandlerRevision::R3
1490 | SecurityHandlerRevision::R4 => {
1491 let owner_pad = Self::pad_password(&owner_password.0);
1493
1494 let mut hash = md5::compute(&owner_pad).to_vec();
1496
1497 if self.revision >= SecurityHandlerRevision::R3 {
1499 for _ in 0..50 {
1500 hash = md5::compute(&hash).to_vec();
1501 }
1502 }
1503
1504 let rc4_key = Rc4Key::from_slice(&hash[..self.key_length]);
1506
1507 let mut decrypted = owner_hash[..32].to_vec();
1509
1510 if self.revision >= SecurityHandlerRevision::R3 {
1512 for i in (0..20).rev() {
1513 let mut key_bytes = hash[..self.key_length].to_vec();
1514 for byte in &mut key_bytes {
1515 *byte ^= i as u8;
1516 }
1517 let iter_key = Rc4Key::from_slice(&key_bytes);
1518 decrypted = rc4_encrypt(&iter_key, &decrypted);
1519 }
1520 } else {
1521 decrypted = rc4_encrypt(&rc4_key, &decrypted);
1523 }
1524
1525 let user_pwd_bytes = decrypted
1531 .iter()
1532 .take_while(|&&b| b != 0x28 || decrypted.starts_with(&PADDING))
1533 .copied()
1534 .collect::<Vec<u8>>();
1535
1536 let recovered_user =
1537 UserPassword(String::from_utf8_lossy(&user_pwd_bytes).to_string());
1538
1539 let computed_owner = self.compute_owner_hash(owner_password, &recovered_user);
1541
1542 Ok(computed_owner[..32] == owner_hash[..32])
1544 }
1545 SecurityHandlerRevision::R5 | SecurityHandlerRevision::R6 => {
1546 Err(crate::error::PdfError::EncryptionError(
1549 "R5/R6 owner password validation not yet implemented (Phase 3)".to_string(),
1550 ))
1551 }
1552 }
1553 }
1554}
1555
1556fn rc4_encrypt(key: &Rc4Key, data: &[u8]) -> Vec<u8> {
1558 let mut cipher = Rc4::new(key);
1559 cipher.process(data)
1560}
1561
1562fn sha256(data: &[u8]) -> Vec<u8> {
1569 Sha256::digest(data).to_vec()
1570}
1571
1572fn sha384(data: &[u8]) -> Vec<u8> {
1577 Sha384::digest(data).to_vec()
1578}
1579
1580fn sha512(data: &[u8]) -> Vec<u8> {
1585 Sha512::digest(data).to_vec()
1586}
1587
1588const ALGORITHM_2B_MIN_ROUNDS: usize = 64;
1594
1595const ALGORITHM_2B_MAX_ROUNDS: usize = 2048;
1597
1598const ALGORITHM_2B_MAX_PASSWORD_LEN: usize = 127;
1601
1602const HASH_SELECTOR_BYTES: usize = 16;
1604
1605pub fn compute_hash_r6_algorithm_2b(
1637 password: &[u8],
1638 salt: &[u8],
1639 u_entry: &[u8],
1640) -> Result<Vec<u8>> {
1641 if password.len() > ALGORITHM_2B_MAX_PASSWORD_LEN {
1643 return Err(crate::error::PdfError::EncryptionError(format!(
1644 "Password too long ({} bytes, max {})",
1645 password.len(),
1646 ALGORITHM_2B_MAX_PASSWORD_LEN
1647 )));
1648 }
1649
1650 let mut input = Vec::with_capacity(password.len() + salt.len() + u_entry.len().min(48));
1652 input.extend_from_slice(password);
1653 input.extend_from_slice(salt);
1654 if !u_entry.is_empty() {
1655 input.extend_from_slice(&u_entry[..u_entry.len().min(48)]);
1656 }
1657
1658 let mut k = sha256(&input);
1659
1660 let mut round: usize = 0;
1662 loop {
1663 let mut k1_unit = Vec::new();
1666 k1_unit.extend_from_slice(password);
1667 k1_unit.extend_from_slice(&k);
1668 if !u_entry.is_empty() {
1669 k1_unit.extend_from_slice(&u_entry[..u_entry.len().min(48)]);
1670 }
1671
1672 let mut k1 = Vec::with_capacity(k1_unit.len() * 64);
1674 for _ in 0..64 {
1675 k1.extend_from_slice(&k1_unit);
1676 }
1677
1678 while k1.len() % 16 != 0 {
1681 k1.push(0);
1682 }
1683
1684 if k.len() < 32 {
1687 while k.len() < 32 {
1689 k.push(0);
1690 }
1691 }
1692
1693 let aes_key = AesKey::new_128(k[..16].to_vec()).map_err(|e| {
1694 crate::error::PdfError::EncryptionError(format!(
1695 "Algorithm 2.B: Failed to create AES key: {}",
1696 e
1697 ))
1698 })?;
1699 let aes = Aes::new(aes_key);
1700 let iv = &k[16..32];
1701
1702 let e = aes.encrypt_cbc_raw(&k1, iv).map_err(|e| {
1703 crate::error::PdfError::EncryptionError(format!(
1704 "Algorithm 2.B: AES encryption failed: {}",
1705 e
1706 ))
1707 })?;
1708
1709 let hash_selector = {
1714 let sum: u64 = e[..HASH_SELECTOR_BYTES.min(e.len())]
1715 .iter()
1716 .map(|&b| b as u64)
1717 .sum();
1718 (sum % 3) as u8
1719 };
1720
1721 k = match hash_selector {
1722 0 => sha256(&e),
1723 1 => sha384(&e),
1724 2 => sha512(&e),
1725 _ => unreachable!("Modulo 3 can only be 0, 1, or 2"),
1726 };
1727
1728 let last_byte = *e.last().unwrap_or(&0);
1731 round += 1;
1732
1733 if round >= ALGORITHM_2B_MIN_ROUNDS {
1734 if (last_byte as usize) <= round.saturating_sub(32) {
1738 break;
1739 }
1740 }
1741
1742 if round >= ALGORITHM_2B_MAX_ROUNDS {
1744 break;
1745 }
1746 }
1747
1748 Ok(k[..32.min(k.len())].to_vec())
1751}
1752
1753const R5_SALT_LENGTH: usize = 8;
1755
1756const R5_HASH_ITERATIONS: usize = 0;
1760
1761const R6_SALT_LENGTH: usize = 8;
1763
1764const U_HASH_LENGTH: usize = 32;
1770
1771const U_VALIDATION_SALT_START: usize = 32;
1773
1774const U_VALIDATION_SALT_END: usize = 40;
1776
1777const U_KEY_SALT_START: usize = 40;
1779
1780const U_KEY_SALT_END: usize = 48;
1782
1783const U_ENTRY_LENGTH: usize = 48;
1785
1786const UE_ENTRY_LENGTH: usize = 32;
1788
1789const PERMS_ENTRY_LENGTH: usize = 16;
1795
1796const PERMS_P_START: usize = 0;
1798
1799const PERMS_P_END: usize = 4;
1801
1802const PERMS_MARKER_START: usize = 4;
1804
1805const PERMS_MARKER_END: usize = 8;
1807
1808const PERMS_LITERAL_START: usize = 8;
1810
1811const PERMS_LITERAL_END: usize = 11;
1813
1814const PERMS_ENCRYPT_META_BYTE: usize = 11;
1816
1817const PERMS_MARKER: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];
1819
1820const PERMS_LITERAL: &[u8; 3] = b"adb";
1822
1823fn generate_salt(len: usize) -> Vec<u8> {
1833 let mut salt = vec![0u8; len];
1834 rand::rng().fill_bytes(&mut salt);
1835 salt
1836}
1837
1838#[cfg(test)]
1839mod tests {
1840 use super::*;
1841
1842 #[test]
1843 fn test_pad_password() {
1844 let padded = StandardSecurityHandler::pad_password("test");
1845 assert_eq!(padded.len(), 32);
1846 assert_eq!(&padded[..4], b"test");
1847 assert_eq!(&padded[4..8], &PADDING[..4]);
1848 }
1849
1850 #[test]
1851 fn test_pad_password_long() {
1852 let long_password = "a".repeat(40);
1853 let padded = StandardSecurityHandler::pad_password(&long_password);
1854 assert_eq!(padded.len(), 32);
1855 assert_eq!(&padded[..32], &long_password.as_bytes()[..32]);
1856 }
1857
1858 #[test]
1859 fn test_rc4_40bit_handler() {
1860 let handler = StandardSecurityHandler::rc4_40bit();
1861 assert_eq!(handler.revision, SecurityHandlerRevision::R2);
1862 assert_eq!(handler.key_length, 5);
1863 }
1864
1865 #[test]
1866 fn test_rc4_128bit_handler() {
1867 let handler = StandardSecurityHandler::rc4_128bit();
1868 assert_eq!(handler.revision, SecurityHandlerRevision::R3);
1869 assert_eq!(handler.key_length, 16);
1870 }
1871
1872 #[test]
1873 fn test_owner_hash_computation() {
1874 let handler = StandardSecurityHandler::rc4_40bit();
1875 let owner_pwd = OwnerPassword("owner".to_string());
1876 let user_pwd = UserPassword("user".to_string());
1877
1878 let hash = handler.compute_owner_hash(&owner_pwd, &user_pwd);
1879 assert_eq!(hash.len(), 32);
1880 }
1881
1882 #[test]
1883 fn test_encryption_key_computation() {
1884 let handler = StandardSecurityHandler::rc4_40bit();
1885 let user_pwd = UserPassword("user".to_string());
1886 let owner_hash = vec![0u8; 32];
1887 let permissions = Permissions::new();
1888
1889 let key = handler
1890 .compute_encryption_key(&user_pwd, &owner_hash, permissions, None)
1891 .unwrap();
1892
1893 assert_eq!(key.len(), 5);
1894 }
1895
1896 #[test]
1897 fn test_aes_256_r5_handler() {
1898 let handler = StandardSecurityHandler::aes_256_r5();
1899 assert_eq!(handler.revision, SecurityHandlerRevision::R5);
1900 assert_eq!(handler.key_length, 32);
1901 }
1902
1903 #[test]
1904 fn test_aes_256_r6_handler() {
1905 let handler = StandardSecurityHandler::aes_256_r6();
1906 assert_eq!(handler.revision, SecurityHandlerRevision::R6);
1907 assert_eq!(handler.key_length, 32);
1908 }
1909
1910 #[test]
1911 fn test_aes_encryption_key_computation() {
1912 let handler = StandardSecurityHandler::aes_256_r5();
1913 let user_pwd = UserPassword("testuser".to_string());
1914 let owner_hash = vec![0u8; 32];
1915 let permissions = Permissions::new();
1916
1917 let key = handler
1918 .compute_aes_encryption_key(&user_pwd, &owner_hash, permissions, None)
1919 .unwrap();
1920
1921 assert_eq!(key.len(), 32);
1922 }
1923
1924 #[test]
1925 fn test_aes_encrypt_decrypt() {
1926 let handler = StandardSecurityHandler::aes_256_r5();
1927 let key = EncryptionKey::new(vec![0u8; 32]);
1928 let obj_id = ObjectId::new(1, 0);
1929 let data = b"Hello AES encryption!";
1930
1931 let encrypted = handler.encrypt_aes(data, &key, &obj_id).unwrap();
1932 assert_ne!(encrypted.as_slice(), data);
1933 assert!(encrypted.len() > data.len()); let _decrypted = handler.decrypt_aes(&encrypted, &key, &obj_id);
1937 }
1939
1940 #[test]
1941 fn test_aes_with_rc4_handler_fails() {
1942 let handler = StandardSecurityHandler::rc4_128bit();
1943 let key = EncryptionKey::new(vec![0u8; 16]);
1944 let obj_id = ObjectId::new(1, 0);
1945 let data = b"test data";
1946
1947 assert!(handler.encrypt_aes(data, &key, &obj_id).is_err());
1949 assert!(handler.decrypt_aes(data, &key, &obj_id).is_err());
1950 }
1951
1952 #[test]
1953 fn test_aes_decrypt_invalid_data() {
1954 let handler = StandardSecurityHandler::aes_256_r5();
1955 let key = EncryptionKey::new(vec![0u8; 32]);
1956 let obj_id = ObjectId::new(1, 0);
1957
1958 let short_data = vec![0u8; 10];
1960 assert!(handler.decrypt_aes(&short_data, &key, &obj_id).is_err());
1961 }
1962
1963 #[test]
1964 fn test_sha256_deterministic() {
1965 let data1 = b"test data";
1966 let data2 = b"test data";
1967 let data3 = b"different data";
1968
1969 let hash1 = sha256(data1);
1970 let hash2 = sha256(data2);
1971 let hash3 = sha256(data3);
1972
1973 assert_eq!(hash1.len(), 32);
1974 assert_eq!(hash2.len(), 32);
1975 assert_eq!(hash3.len(), 32);
1976
1977 assert_eq!(hash1, hash2); assert_ne!(hash1, hash3); }
1980
1981 #[test]
1982 fn test_security_handler_revision_ordering() {
1983 assert!(SecurityHandlerRevision::R2 < SecurityHandlerRevision::R3);
1984 assert!(SecurityHandlerRevision::R3 < SecurityHandlerRevision::R4);
1985 assert!(SecurityHandlerRevision::R4 < SecurityHandlerRevision::R5);
1986 assert!(SecurityHandlerRevision::R5 < SecurityHandlerRevision::R6);
1987 }
1988
1989 #[test]
1990 fn test_aes_password_validation() {
1991 let handler = StandardSecurityHandler::aes_256_r5();
1992 let password = UserPassword("testpassword".to_string());
1993 let user_hash = vec![0u8; 32]; let permissions = Permissions::new();
1995
1996 let result = handler.validate_aes_user_password(&password, &user_hash, permissions, None);
1998 assert!(result.is_ok());
1999 }
2000
2001 #[test]
2004 fn test_user_password_debug() {
2005 let pwd = UserPassword("debug_test".to_string());
2006 let debug_str = format!("{pwd:?}");
2007 assert!(debug_str.contains("UserPassword"));
2008 assert!(debug_str.contains("debug_test"));
2009 }
2010
2011 #[test]
2012 fn test_owner_password_debug() {
2013 let pwd = OwnerPassword("owner_debug".to_string());
2014 let debug_str = format!("{pwd:?}");
2015 assert!(debug_str.contains("OwnerPassword"));
2016 assert!(debug_str.contains("owner_debug"));
2017 }
2018
2019 #[test]
2020 fn test_encryption_key_debug() {
2021 let key = EncryptionKey::new(vec![0x01, 0x02, 0x03]);
2022 let debug_str = format!("{key:?}");
2023 assert!(debug_str.contains("EncryptionKey"));
2024 }
2025
2026 #[test]
2027 fn test_security_handler_revision_equality() {
2028 assert_eq!(SecurityHandlerRevision::R2, SecurityHandlerRevision::R2);
2029 assert_ne!(SecurityHandlerRevision::R2, SecurityHandlerRevision::R3);
2030 }
2031
2032 #[test]
2033 fn test_security_handler_revision_values() {
2034 assert_eq!(SecurityHandlerRevision::R2 as u8, 2);
2035 assert_eq!(SecurityHandlerRevision::R3 as u8, 3);
2036 assert_eq!(SecurityHandlerRevision::R4 as u8, 4);
2037 assert_eq!(SecurityHandlerRevision::R5 as u8, 5);
2038 assert_eq!(SecurityHandlerRevision::R6 as u8, 6);
2039 }
2040
2041 #[test]
2042 fn test_pad_password_various_lengths() {
2043 for len in 0..=40 {
2044 let password = "x".repeat(len);
2045 let padded = StandardSecurityHandler::pad_password(&password);
2046 assert_eq!(padded.len(), 32);
2047
2048 if len <= 32 {
2049 assert_eq!(&padded[..len], password.as_bytes());
2050 } else {
2051 assert_eq!(&padded[..], &password.as_bytes()[..32]);
2052 }
2053 }
2054 }
2055
2056 #[test]
2057 fn test_pad_password_unicode() {
2058 let padded = StandardSecurityHandler::pad_password("café");
2059 assert_eq!(padded.len(), 32);
2060 assert_eq!(&padded[..5], "café".as_bytes());
2062 }
2063
2064 #[test]
2065 fn test_compute_owner_hash_different_users() {
2066 let handler = StandardSecurityHandler::rc4_128bit();
2067 let owner = OwnerPassword("owner".to_string());
2068 let user1 = UserPassword("user1".to_string());
2069 let user2 = UserPassword("user2".to_string());
2070
2071 let hash1 = handler.compute_owner_hash(&owner, &user1);
2072 let hash2 = handler.compute_owner_hash(&owner, &user2);
2073
2074 assert_ne!(hash1, hash2); }
2076
2077 #[test]
2078 fn test_compute_user_hash_r4() {
2079 let handler = StandardSecurityHandler {
2080 revision: SecurityHandlerRevision::R4,
2081 key_length: 16,
2082 };
2083 let user = UserPassword("r4test".to_string());
2084 let owner_hash = vec![0xAA; 32];
2085 let permissions = Permissions::new();
2086
2087 let hash = handler
2088 .compute_user_hash(&user, &owner_hash, permissions, None)
2089 .unwrap();
2090 assert_eq!(hash.len(), 32);
2091 }
2092
2093 #[test]
2094 fn test_compute_user_hash_r6() {
2095 let handler = StandardSecurityHandler::aes_256_r6();
2096 let user = UserPassword("r6test".to_string());
2097 let owner_hash = vec![0xBB; 32];
2098 let permissions = Permissions::all();
2099
2100 let hash = handler
2101 .compute_user_hash(&user, &owner_hash, permissions, None)
2102 .unwrap();
2103 assert_eq!(hash.len(), 32);
2104 }
2105
2106 #[test]
2107 fn test_encryption_key_with_file_id_affects_result() {
2108 let handler = StandardSecurityHandler::rc4_128bit();
2109 let user = UserPassword("test".to_string());
2110 let owner_hash = vec![0xFF; 32];
2111 let permissions = Permissions::new();
2112 let file_id = b"unique_file_id_12345";
2113
2114 let key_with_id = handler
2115 .compute_encryption_key(&user, &owner_hash, permissions, Some(file_id))
2116 .unwrap();
2117 let key_without_id = handler
2118 .compute_encryption_key(&user, &owner_hash, permissions, None)
2119 .unwrap();
2120
2121 assert_ne!(key_with_id.key, key_without_id.key);
2122 }
2123
2124 #[test]
2125 fn test_encrypt_string_empty() {
2126 let handler = StandardSecurityHandler::rc4_40bit();
2127 let key = EncryptionKey::new(vec![0x01, 0x02, 0x03, 0x04, 0x05]);
2128 let obj_id = ObjectId::new(1, 0);
2129
2130 let encrypted = handler.encrypt_string(b"", &key, &obj_id);
2131 assert_eq!(encrypted.len(), 0);
2132 }
2133
2134 #[test]
2135 fn test_encrypt_decrypt_large_data() {
2136 let handler = StandardSecurityHandler::rc4_128bit();
2137 let key = EncryptionKey::new(vec![0xAA; 16]);
2138 let obj_id = ObjectId::new(42, 0);
2139 let large_data = vec![0x55; 10000]; let encrypted = handler.encrypt_string(&large_data, &key, &obj_id);
2142 assert_eq!(encrypted.len(), large_data.len());
2143 assert_ne!(encrypted, large_data);
2144
2145 let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id);
2146 assert_eq!(decrypted, large_data);
2147 }
2148
2149 #[test]
2150 fn test_stream_encryption_different_from_string() {
2151 let handler = StandardSecurityHandler::rc4_128bit();
2153 let key = EncryptionKey::new(vec![0x11; 16]);
2154 let obj_id = ObjectId::new(5, 1);
2155 let data = b"Stream content test";
2156
2157 let encrypted_string = handler.encrypt_string(data, &key, &obj_id);
2158 let encrypted_stream = handler.encrypt_stream(data, &key, &obj_id);
2159
2160 assert_eq!(encrypted_string, encrypted_stream); }
2162
2163 #[test]
2164 fn test_aes_encryption_with_different_object_ids() {
2165 let handler = StandardSecurityHandler::aes_256_r5();
2166 let key = EncryptionKey::new(vec![0x77; 32]);
2167 let obj_id1 = ObjectId::new(10, 0);
2168 let obj_id2 = ObjectId::new(11, 0);
2169 let data = b"AES test data";
2170
2171 let encrypted1 = handler.encrypt_aes(data, &key, &obj_id1).unwrap();
2172 let encrypted2 = handler.encrypt_aes(data, &key, &obj_id2).unwrap();
2173
2174 assert_ne!(encrypted1, encrypted2);
2176 }
2177
2178 #[test]
2179 fn test_aes_decrypt_invalid_iv_length() {
2180 let handler = StandardSecurityHandler::aes_256_r5();
2181 let key = EncryptionKey::new(vec![0x88; 32]);
2182 let obj_id = ObjectId::new(1, 0);
2183
2184 let short_data = vec![0u8; 10];
2186 assert!(handler.decrypt_aes(&short_data, &key, &obj_id).is_err());
2187
2188 let iv_only = vec![0u8; 16];
2190 let result = handler.decrypt_aes(&iv_only, &key, &obj_id);
2191 if let Ok(decrypted) = result {
2193 assert_eq!(decrypted.len(), 0);
2194 }
2195 }
2196
2197 #[test]
2198 fn test_aes_validate_password_wrong_hash_length() {
2199 let handler = StandardSecurityHandler::aes_256_r5();
2200 let password = UserPassword("test".to_string());
2201 let short_hash = vec![0u8; 16]; let permissions = Permissions::new();
2203
2204 let result = handler
2205 .validate_aes_user_password(&password, &short_hash, permissions, None)
2206 .unwrap();
2207 assert!(!result); }
2209
2210 #[test]
2211 fn test_permissions_affect_encryption_key() {
2212 let handler = StandardSecurityHandler::rc4_128bit();
2213 let user = UserPassword("same_user".to_string());
2214 let owner_hash = vec![0xCC; 32];
2215
2216 let perms1 = Permissions::new();
2217 let perms2 = Permissions::all();
2218
2219 let key1 = handler
2220 .compute_encryption_key(&user, &owner_hash, perms1, None)
2221 .unwrap();
2222 let key2 = handler
2223 .compute_encryption_key(&user, &owner_hash, perms2, None)
2224 .unwrap();
2225
2226 assert_ne!(key1.key, key2.key); }
2228
2229 #[test]
2230 fn test_different_handlers_produce_different_keys() {
2231 let user = UserPassword("test".to_string());
2232 let owner_hash = vec![0xDD; 32];
2233 let permissions = Permissions::new();
2234
2235 let handler_r2 = StandardSecurityHandler::rc4_40bit();
2236 let handler_r3 = StandardSecurityHandler::rc4_128bit();
2237
2238 let key_r2 = handler_r2
2239 .compute_encryption_key(&user, &owner_hash, permissions, None)
2240 .unwrap();
2241 let key_r3 = handler_r3
2242 .compute_encryption_key(&user, &owner_hash, permissions, None)
2243 .unwrap();
2244
2245 assert_ne!(key_r2.len(), key_r3.len()); assert_eq!(key_r2.len(), 5);
2247 assert_eq!(key_r3.len(), 16);
2248 }
2249
2250 #[test]
2251 fn test_full_workflow_aes_r6() {
2252 let handler = StandardSecurityHandler::aes_256_r6();
2253 let user_pwd = UserPassword("user_r6".to_string());
2254 let permissions = Permissions::new();
2255 let file_id = b"test_file_r6";
2256
2257 let owner_hash = vec![0x42; 32]; let user_hash = handler
2262 .compute_user_hash(&user_pwd, &owner_hash, permissions, Some(file_id))
2263 .unwrap();
2264 assert_eq!(user_hash.len(), 32);
2265
2266 let key = handler
2268 .compute_aes_encryption_key(&user_pwd, &owner_hash, permissions, Some(file_id))
2269 .unwrap();
2270 assert_eq!(key.len(), 32);
2271
2272 let obj_id = ObjectId::new(100, 5);
2274 let content = b"R6 AES encryption test";
2275 let encrypted = handler.encrypt_string(content, &key, &obj_id);
2276
2277 if !encrypted.is_empty() {
2279 assert_ne!(encrypted.as_slice(), content);
2280 }
2281 }
2282
2283 #[test]
2284 fn test_md5_compute_consistency() {
2285 let data = b"consistent data for md5";
2286 let hash1 = md5::compute(data);
2287 let hash2 = md5::compute(data);
2288
2289 assert_eq!(hash1, hash2);
2290 assert_eq!(hash1.len(), 16);
2291 }
2292
2293 #[test]
2294 fn test_sha256_consistency() {
2295 let data = b"consistent data for sha256";
2296 let hash1 = sha256(data);
2297 let hash2 = sha256(data);
2298
2299 assert_eq!(hash1, hash2);
2300 assert_eq!(hash1.len(), 32);
2301 }
2302
2303 #[test]
2304 fn test_rc4_encrypt_helper() {
2305 let key = Rc4Key::from_slice(&[0x01, 0x02, 0x03, 0x04, 0x05]);
2306 let data = b"test rc4 helper";
2307
2308 let encrypted = rc4_encrypt(&key, data);
2309 assert_ne!(encrypted.as_slice(), data);
2310
2311 let decrypted = rc4_encrypt(&key, &encrypted);
2313 assert_eq!(decrypted.as_slice(), data);
2314 }
2315
2316 #[test]
2317 fn test_edge_case_max_object_generation() {
2318 let handler = StandardSecurityHandler::rc4_128bit();
2319 let key = EncryptionKey::new(vec![0xEE; 16]);
2320 let obj_id = ObjectId::new(0xFFFFFF, 0xFFFF); let data = b"edge case";
2322
2323 let encrypted = handler.encrypt_string(data, &key, &obj_id);
2324 let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id);
2325 assert_eq!(decrypted.as_slice(), data);
2326 }
2327
2328 #[test]
2331 fn test_sha256_nist_empty_string() {
2332 let hash = sha256(b"");
2334 let expected: [u8; 32] = [
2335 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f,
2336 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
2337 0x78, 0x52, 0xb8, 0x55,
2338 ];
2339 assert_eq!(
2340 hash.as_slice(),
2341 expected.as_slice(),
2342 "SHA-256('') must match NIST test vector"
2343 );
2344 }
2345
2346 #[test]
2347 fn test_sha256_nist_abc() {
2348 let hash = sha256(b"abc");
2350 let expected: [u8; 32] = [
2351 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
2352 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
2353 0xf2, 0x00, 0x15, 0xad,
2354 ];
2355 assert_eq!(
2356 hash.as_slice(),
2357 expected.as_slice(),
2358 "SHA-256('abc') must match NIST test vector"
2359 );
2360 }
2361
2362 #[test]
2363 fn test_sha512_nist_abc() {
2364 let hash = sha512(b"abc");
2366 let expected: [u8; 64] = [
2367 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20,
2368 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6,
2369 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba,
2370 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
2371 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
2372 ];
2373 assert_eq!(
2374 hash.as_slice(),
2375 expected.as_slice(),
2376 "SHA-512('abc') must match NIST test vector"
2377 );
2378 }
2379
2380 #[test]
2381 fn test_sha512_length() {
2382 let hash = sha512(b"test data");
2383 assert_eq!(hash.len(), 64, "SHA-512 must produce 64 bytes");
2384 }
2385
2386 #[test]
2387 fn test_sha512_deterministic() {
2388 let data1 = b"sha512 test data";
2389 let data2 = b"sha512 test data";
2390 let data3 = b"different data";
2391
2392 let hash1 = sha512(data1);
2393 let hash2 = sha512(data2);
2394 let hash3 = sha512(data3);
2395
2396 assert_eq!(hash1, hash2, "Same input must produce same SHA-512 hash");
2397 assert_ne!(hash1, hash3, "Different input must produce different hash");
2398 }
2399
2400 #[test]
2403 fn test_r5_user_hash_computation() {
2404 let handler = StandardSecurityHandler::aes_256_r5();
2405 let password = UserPassword("test_password".to_string());
2406
2407 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2408
2409 assert_eq!(u_entry.len(), 48, "R5 U entry must be 48 bytes");
2411 }
2412
2413 #[test]
2414 fn test_r5_user_password_validation_correct() {
2415 let handler = StandardSecurityHandler::aes_256_r5();
2416 let password = UserPassword("correct_password".to_string());
2417
2418 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2420
2421 let is_valid = handler
2423 .validate_r5_user_password(&password, &u_entry)
2424 .unwrap();
2425 assert!(is_valid, "Correct password must validate");
2426 }
2427
2428 #[test]
2429 fn test_r5_user_password_validation_incorrect() {
2430 let handler = StandardSecurityHandler::aes_256_r5();
2431 let correct_password = UserPassword("correct_password".to_string());
2432 let wrong_password = UserPassword("wrong_password".to_string());
2433
2434 let u_entry = handler.compute_r5_user_hash(&correct_password).unwrap();
2436
2437 let is_valid = handler
2439 .validate_r5_user_password(&wrong_password, &u_entry)
2440 .unwrap();
2441 assert!(!is_valid, "Wrong password must not validate");
2442 }
2443
2444 #[test]
2445 fn test_r5_user_hash_random_salts() {
2446 let handler = StandardSecurityHandler::aes_256_r5();
2447 let password = UserPassword("same_password".to_string());
2448
2449 let u_entry1 = handler.compute_r5_user_hash(&password).unwrap();
2451 let u_entry2 = handler.compute_r5_user_hash(&password).unwrap();
2452
2453 assert_ne!(
2455 &u_entry1[..32],
2456 &u_entry2[..32],
2457 "Different random salts should produce different hashes"
2458 );
2459
2460 assert_ne!(
2462 &u_entry1[32..40],
2463 &u_entry2[32..40],
2464 "Validation salts must be random"
2465 );
2466
2467 assert!(handler
2469 .validate_r5_user_password(&password, &u_entry1)
2470 .unwrap());
2471 assert!(handler
2472 .validate_r5_user_password(&password, &u_entry2)
2473 .unwrap());
2474 }
2475
2476 #[test]
2477 fn test_r5_user_hash_invalid_entry_length() {
2478 let handler = StandardSecurityHandler::aes_256_r5();
2479 let password = UserPassword("test".to_string());
2480
2481 let short_entry = vec![0u8; 32]; let result = handler.validate_r5_user_password(&password, &short_entry);
2484 assert!(result.is_err(), "Short U entry must fail");
2485
2486 let long_entry = vec![0u8; 64]; let result = handler.validate_r5_user_password(&password, &long_entry);
2488 assert!(result.is_err(), "Long U entry must fail");
2489 }
2490
2491 #[test]
2492 fn test_r5_empty_password() {
2493 let handler = StandardSecurityHandler::aes_256_r5();
2494 let empty_password = UserPassword("".to_string());
2495
2496 let u_entry = handler.compute_r5_user_hash(&empty_password).unwrap();
2498 assert_eq!(u_entry.len(), 48);
2499
2500 let is_valid = handler
2501 .validate_r5_user_password(&empty_password, &u_entry)
2502 .unwrap();
2503 assert!(is_valid, "Empty password must validate correctly");
2504
2505 let non_empty = UserPassword("not_empty".to_string());
2507 let is_valid = handler
2508 .validate_r5_user_password(&non_empty, &u_entry)
2509 .unwrap();
2510 assert!(!is_valid, "Non-empty password must not validate");
2511 }
2512
2513 #[test]
2516 fn test_r5_ue_entry_computation() {
2517 let handler = StandardSecurityHandler::aes_256_r5();
2518 let password = UserPassword("ue_test_password".to_string());
2519 let encryption_key = EncryptionKey::new(vec![0xAB; 32]);
2520
2521 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2523
2524 let ue_entry = handler
2526 .compute_r5_ue_entry(&password, &u_entry, &encryption_key)
2527 .unwrap();
2528
2529 assert_eq!(ue_entry.len(), 32, "R5 UE entry must be 32 bytes");
2531
2532 assert_ne!(
2534 ue_entry.as_slice(),
2535 encryption_key.as_bytes(),
2536 "UE must be encrypted"
2537 );
2538 }
2539
2540 #[test]
2541 fn test_r5_encryption_key_recovery() {
2542 let handler = StandardSecurityHandler::aes_256_r5();
2543 let password = UserPassword("recovery_test".to_string());
2544 let original_key = EncryptionKey::new(vec![0x42; 32]);
2545
2546 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2548
2549 let ue_entry = handler
2551 .compute_r5_ue_entry(&password, &u_entry, &original_key)
2552 .unwrap();
2553
2554 let recovered_key = handler
2556 .recover_r5_encryption_key(&password, &u_entry, &ue_entry)
2557 .unwrap();
2558
2559 assert_eq!(
2561 recovered_key.as_bytes(),
2562 original_key.as_bytes(),
2563 "Recovered key must match original"
2564 );
2565 }
2566
2567 #[test]
2568 fn test_r5_ue_wrong_password_fails() {
2569 let handler = StandardSecurityHandler::aes_256_r5();
2570 let correct_password = UserPassword("correct".to_string());
2571 let wrong_password = UserPassword("wrong".to_string());
2572 let original_key = EncryptionKey::new(vec![0x99; 32]);
2573
2574 let u_entry = handler.compute_r5_user_hash(&correct_password).unwrap();
2576 let ue_entry = handler
2577 .compute_r5_ue_entry(&correct_password, &u_entry, &original_key)
2578 .unwrap();
2579
2580 let recovered_key = handler
2582 .recover_r5_encryption_key(&wrong_password, &u_entry, &ue_entry)
2583 .unwrap();
2584
2585 assert_ne!(
2587 recovered_key.as_bytes(),
2588 original_key.as_bytes(),
2589 "Wrong password must produce wrong key"
2590 );
2591 }
2592
2593 #[test]
2594 fn test_r5_ue_invalid_length() {
2595 let handler = StandardSecurityHandler::aes_256_r5();
2596 let password = UserPassword("test".to_string());
2597 let u_entry = vec![0u8; 48]; let short_ue = vec![0u8; 16]; let result = handler.recover_r5_encryption_key(&password, &u_entry, &short_ue);
2602 assert!(result.is_err(), "Short UE entry must fail");
2603
2604 let long_ue = vec![0u8; 64]; let result = handler.recover_r5_encryption_key(&password, &u_entry, &long_ue);
2606 assert!(result.is_err(), "Long UE entry must fail");
2607 }
2608
2609 #[test]
2610 fn test_r5_ue_invalid_u_length() {
2611 let handler = StandardSecurityHandler::aes_256_r5();
2612 let password = UserPassword("test".to_string());
2613 let encryption_key = EncryptionKey::new(vec![0x11; 32]);
2614
2615 let short_u = vec![0u8; 32]; let result = handler.compute_r5_ue_entry(&password, &short_u, &encryption_key);
2618 assert!(
2619 result.is_err(),
2620 "Short U entry must fail for UE computation"
2621 );
2622 }
2623
2624 #[test]
2625 fn test_r5_full_workflow_u_ue() {
2626 let handler = StandardSecurityHandler::aes_256_r5();
2627 let password = UserPassword("full_workflow_test".to_string());
2628 let encryption_key = EncryptionKey::new((0..32).collect::<Vec<u8>>());
2629
2630 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2632 assert_eq!(u_entry.len(), 48);
2633
2634 assert!(handler
2636 .validate_r5_user_password(&password, &u_entry)
2637 .unwrap());
2638
2639 let ue_entry = handler
2641 .compute_r5_ue_entry(&password, &u_entry, &encryption_key)
2642 .unwrap();
2643 assert_eq!(ue_entry.len(), 32);
2644
2645 let recovered = handler
2647 .recover_r5_encryption_key(&password, &u_entry, &ue_entry)
2648 .unwrap();
2649
2650 assert_eq!(
2652 recovered.as_bytes(),
2653 encryption_key.as_bytes(),
2654 "Full R5 workflow: recovered key must match original"
2655 );
2656 }
2657
2658 #[test]
2661 fn test_r6_user_hash_computation() {
2662 let handler = StandardSecurityHandler::aes_256_r6();
2663 let password = UserPassword("r6_test_password".to_string());
2664
2665 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2666
2667 assert_eq!(u_entry.len(), 48, "R6 U entry must be 48 bytes");
2669 }
2670
2671 #[test]
2672 fn test_r6_user_password_validation_correct() {
2673 let handler = StandardSecurityHandler::aes_256_r6();
2674 let password = UserPassword("r6_correct_password".to_string());
2675
2676 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2678
2679 let is_valid = handler
2681 .validate_r6_user_password(&password, &u_entry)
2682 .unwrap();
2683 assert!(is_valid, "Correct R6 password must validate");
2684 }
2685
2686 #[test]
2687 fn test_r6_user_password_validation_incorrect() {
2688 let handler = StandardSecurityHandler::aes_256_r6();
2689 let correct_password = UserPassword("r6_correct".to_string());
2690 let wrong_password = UserPassword("r6_wrong".to_string());
2691
2692 let u_entry = handler.compute_r6_user_hash(&correct_password).unwrap();
2694
2695 let is_valid = handler
2697 .validate_r6_user_password(&wrong_password, &u_entry)
2698 .unwrap();
2699 assert!(!is_valid, "Wrong R6 password must not validate");
2700 }
2701
2702 #[test]
2703 fn test_r6_uses_sha512_not_sha256() {
2704 let handler_r5 = StandardSecurityHandler::aes_256_r5();
2706 let handler_r6 = StandardSecurityHandler::aes_256_r6();
2707 let password = UserPassword("same_password_both_revisions".to_string());
2708
2709 let u_r5 = handler_r5.compute_r5_user_hash(&password).unwrap();
2710 let u_r6 = handler_r6.compute_r6_user_hash(&password).unwrap();
2711
2712 assert_ne!(
2715 &u_r5[..32],
2716 &u_r6[..32],
2717 "R5 (SHA-256) and R6 (SHA-512) must produce different hashes"
2718 );
2719 }
2720
2721 #[test]
2722 fn test_r6_unicode_password() {
2723 let handler = StandardSecurityHandler::aes_256_r6();
2724 let unicode_password = UserPassword("café🔒日本語".to_string());
2725
2726 let u_entry = handler.compute_r6_user_hash(&unicode_password).unwrap();
2727 assert_eq!(u_entry.len(), 48);
2728
2729 let is_valid = handler
2731 .validate_r6_user_password(&unicode_password, &u_entry)
2732 .unwrap();
2733 assert!(is_valid, "Unicode password must validate");
2734
2735 let different_unicode = UserPassword("café🔓日本語".to_string()); let is_valid = handler
2738 .validate_r6_user_password(&different_unicode, &u_entry)
2739 .unwrap();
2740 assert!(!is_valid, "Different Unicode password must not validate");
2741 }
2742
2743 #[test]
2746 fn test_r6_ue_entry_computation() {
2747 let handler = StandardSecurityHandler::aes_256_r6();
2748 let password = UserPassword("r6_ue_test".to_string());
2749 let encryption_key = EncryptionKey::new(vec![0xCD; 32]);
2750
2751 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2752 let ue_entry = handler
2753 .compute_r6_ue_entry(&password, &u_entry, &encryption_key)
2754 .unwrap();
2755
2756 assert_eq!(ue_entry.len(), 32, "R6 UE entry must be 32 bytes");
2757 }
2758
2759 #[test]
2760 fn test_r6_encryption_key_recovery() {
2761 let handler = StandardSecurityHandler::aes_256_r6();
2762 let password = UserPassword("r6_recovery_test".to_string());
2763 let original_key = EncryptionKey::new(vec![0xEF; 32]);
2764
2765 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2766 let ue_entry = handler
2767 .compute_r6_ue_entry(&password, &u_entry, &original_key)
2768 .unwrap();
2769
2770 let recovered_key = handler
2771 .recover_r6_encryption_key(&password, &u_entry, &ue_entry)
2772 .unwrap();
2773
2774 assert_eq!(
2775 recovered_key.as_bytes(),
2776 original_key.as_bytes(),
2777 "R6: Recovered key must match original"
2778 );
2779 }
2780
2781 #[test]
2784 fn test_r6_perms_entry_computation() {
2785 let handler = StandardSecurityHandler::aes_256_r6();
2786 let permissions = Permissions::all();
2787 let key = EncryptionKey::new(vec![0x42; 32]);
2788
2789 let perms = handler
2790 .compute_r6_perms_entry(permissions, &key, true)
2791 .unwrap();
2792
2793 assert_eq!(perms.len(), 16, "Perms entry must be 16 bytes");
2794 }
2795
2796 #[test]
2797 fn test_r6_perms_validation() {
2798 let handler = StandardSecurityHandler::aes_256_r6();
2799 let permissions = Permissions::new();
2800 let key = EncryptionKey::new(vec![0x55; 32]);
2801
2802 let perms = handler
2803 .compute_r6_perms_entry(permissions, &key, false)
2804 .unwrap();
2805
2806 let is_valid = handler
2807 .validate_r6_perms(&perms, &key, permissions)
2808 .unwrap();
2809 assert!(is_valid, "Perms validation must succeed with correct key");
2810 }
2811
2812 #[test]
2813 fn test_r6_perms_wrong_key_fails() {
2814 let handler = StandardSecurityHandler::aes_256_r6();
2815 let permissions = Permissions::all();
2816 let correct_key = EncryptionKey::new(vec![0xAA; 32]);
2817 let wrong_key = EncryptionKey::new(vec![0xBB; 32]);
2818
2819 let perms = handler
2820 .compute_r6_perms_entry(permissions, &correct_key, true)
2821 .unwrap();
2822
2823 let result = handler.validate_r6_perms(&perms, &wrong_key, permissions);
2825 assert!(result.is_ok()); assert!(!result.unwrap()); }
2828
2829 #[test]
2830 fn test_r6_perms_encrypt_metadata_flag() {
2831 let handler = StandardSecurityHandler::aes_256_r6();
2832 let permissions = Permissions::new();
2833 let key = EncryptionKey::new(vec![0x33; 32]);
2834
2835 let perms_true = handler
2836 .compute_r6_perms_entry(permissions, &key, true)
2837 .unwrap();
2838 let perms_false = handler
2839 .compute_r6_perms_entry(permissions, &key, false)
2840 .unwrap();
2841
2842 assert_ne!(
2844 perms_true, perms_false,
2845 "Different EncryptMetadata must produce different Perms"
2846 );
2847
2848 let flag_true = handler
2850 .extract_r6_encrypt_metadata(&perms_true, &key)
2851 .unwrap();
2852 assert_eq!(flag_true, Some(true));
2853
2854 let flag_false = handler
2855 .extract_r6_encrypt_metadata(&perms_false, &key)
2856 .unwrap();
2857 assert_eq!(flag_false, Some(false));
2858 }
2859
2860 #[test]
2861 fn test_r6_perms_invalid_length() {
2862 let handler = StandardSecurityHandler::aes_256_r6();
2863 let key = EncryptionKey::new(vec![0x44; 32]);
2864 let permissions = Permissions::new();
2865
2866 let invalid_perms = vec![0u8; 12]; let result = handler.validate_r6_perms(&invalid_perms, &key, permissions);
2868 assert!(result.is_err(), "Short Perms entry must fail");
2869 }
2870
2871 #[test]
2872 fn test_r6_full_workflow_with_perms() {
2873 let handler = StandardSecurityHandler::aes_256_r6();
2875 let password = UserPassword("r6_full_workflow".to_string());
2876 let permissions = Permissions::all();
2877 let encryption_key = EncryptionKey::new((0..32).map(|i| (i * 3) as u8).collect());
2878
2879 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2881 assert_eq!(u_entry.len(), 48);
2882
2883 assert!(handler
2885 .validate_r6_user_password(&password, &u_entry)
2886 .unwrap());
2887
2888 let ue_entry = handler
2890 .compute_r6_ue_entry(&password, &u_entry, &encryption_key)
2891 .unwrap();
2892 assert_eq!(ue_entry.len(), 32);
2893
2894 let perms = handler
2896 .compute_r6_perms_entry(permissions, &encryption_key, true)
2897 .unwrap();
2898 assert_eq!(perms.len(), 16);
2899
2900 let recovered_key = handler
2902 .recover_r6_encryption_key(&password, &u_entry, &ue_entry)
2903 .unwrap();
2904 assert_eq!(
2905 recovered_key.as_bytes(),
2906 encryption_key.as_bytes(),
2907 "Recovered key must match original"
2908 );
2909
2910 let perms_valid = handler
2912 .validate_r6_perms(&perms, &recovered_key, permissions)
2913 .unwrap();
2914 assert!(perms_valid, "Perms must validate with recovered key");
2915
2916 let encrypt_meta = handler
2918 .extract_r6_encrypt_metadata(&perms, &recovered_key)
2919 .unwrap();
2920 assert_eq!(encrypt_meta, Some(true), "EncryptMetadata must be true");
2921 }
2922}