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_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(
1488 &self,
1489 owner_password: &OwnerPassword,
1490 owner_hash: &[u8],
1491 _user_password: &UserPassword, _permissions: Permissions,
1493 _file_id: Option<&[u8]>,
1494 u_entry: Option<&[u8]>,
1495 ) -> Result<bool> {
1496 match self.revision {
1497 SecurityHandlerRevision::R2
1498 | SecurityHandlerRevision::R3
1499 | SecurityHandlerRevision::R4 => {
1500 let owner_pad = Self::pad_password(&owner_password.0);
1502
1503 let mut hash = md5::compute(&owner_pad).to_vec();
1505
1506 if self.revision >= SecurityHandlerRevision::R3 {
1508 for _ in 0..50 {
1509 hash = md5::compute(&hash).to_vec();
1510 }
1511 }
1512
1513 let rc4_key = Rc4Key::from_slice(&hash[..self.key_length]);
1515
1516 let mut decrypted = owner_hash[..32].to_vec();
1518
1519 if self.revision >= SecurityHandlerRevision::R3 {
1521 for i in (0..20).rev() {
1522 let mut key_bytes = hash[..self.key_length].to_vec();
1523 for byte in &mut key_bytes {
1524 *byte ^= i as u8;
1525 }
1526 let iter_key = Rc4Key::from_slice(&key_bytes);
1527 decrypted = rc4_encrypt(&iter_key, &decrypted);
1528 }
1529 } else {
1530 decrypted = rc4_encrypt(&rc4_key, &decrypted);
1532 }
1533
1534 let user_pwd_bytes = decrypted
1540 .iter()
1541 .take_while(|&&b| b != 0x28 || decrypted.starts_with(&PADDING))
1542 .copied()
1543 .collect::<Vec<u8>>();
1544
1545 let recovered_user =
1546 UserPassword(String::from_utf8_lossy(&user_pwd_bytes).to_string());
1547
1548 let computed_owner = self.compute_owner_hash(owner_password, &recovered_user);
1550
1551 Ok(computed_owner[..32] == owner_hash[..32])
1553 }
1554 SecurityHandlerRevision::R5 => {
1555 self.validate_r5_owner_password(owner_password, owner_hash)
1558 }
1559 SecurityHandlerRevision::R6 => {
1560 let u = u_entry.ok_or_else(|| {
1562 crate::error::PdfError::EncryptionError(
1563 "R6 owner password validation requires U entry".to_string(),
1564 )
1565 })?;
1566 self.validate_r6_owner_password(owner_password, owner_hash, u)
1567 }
1568 }
1569 }
1570}
1571
1572fn rc4_encrypt(key: &Rc4Key, data: &[u8]) -> Vec<u8> {
1574 let mut cipher = Rc4::new(key);
1575 cipher.process(data)
1576}
1577
1578fn sha256(data: &[u8]) -> Vec<u8> {
1585 Sha256::digest(data).to_vec()
1586}
1587
1588fn sha384(data: &[u8]) -> Vec<u8> {
1593 Sha384::digest(data).to_vec()
1594}
1595
1596fn sha512(data: &[u8]) -> Vec<u8> {
1601 Sha512::digest(data).to_vec()
1602}
1603
1604const ALGORITHM_2B_MIN_ROUNDS: usize = 64;
1610
1611const ALGORITHM_2B_MAX_ROUNDS: usize = 2048;
1613
1614const ALGORITHM_2B_MAX_PASSWORD_LEN: usize = 127;
1617
1618const HASH_SELECTOR_BYTES: usize = 16;
1620
1621pub fn compute_hash_r6_algorithm_2b(
1653 password: &[u8],
1654 salt: &[u8],
1655 u_entry: &[u8],
1656) -> Result<Vec<u8>> {
1657 if password.len() > ALGORITHM_2B_MAX_PASSWORD_LEN {
1659 return Err(crate::error::PdfError::EncryptionError(format!(
1660 "Password too long ({} bytes, max {})",
1661 password.len(),
1662 ALGORITHM_2B_MAX_PASSWORD_LEN
1663 )));
1664 }
1665
1666 let mut input = Vec::with_capacity(password.len() + salt.len() + u_entry.len().min(48));
1668 input.extend_from_slice(password);
1669 input.extend_from_slice(salt);
1670 if !u_entry.is_empty() {
1671 input.extend_from_slice(&u_entry[..u_entry.len().min(48)]);
1672 }
1673
1674 let mut k = sha256(&input);
1675
1676 let mut round: usize = 0;
1678 loop {
1679 let mut k1_unit = Vec::new();
1682 k1_unit.extend_from_slice(password);
1683 k1_unit.extend_from_slice(&k);
1684 if !u_entry.is_empty() {
1685 k1_unit.extend_from_slice(&u_entry[..u_entry.len().min(48)]);
1686 }
1687
1688 let mut k1 = Vec::with_capacity(k1_unit.len() * 64);
1690 for _ in 0..64 {
1691 k1.extend_from_slice(&k1_unit);
1692 }
1693
1694 while k1.len() % 16 != 0 {
1697 k1.push(0);
1698 }
1699
1700 if k.len() < 32 {
1703 while k.len() < 32 {
1705 k.push(0);
1706 }
1707 }
1708
1709 let aes_key = AesKey::new_128(k[..16].to_vec()).map_err(|e| {
1710 crate::error::PdfError::EncryptionError(format!(
1711 "Algorithm 2.B: Failed to create AES key: {}",
1712 e
1713 ))
1714 })?;
1715 let aes = Aes::new(aes_key);
1716 let iv = &k[16..32];
1717
1718 let e = aes.encrypt_cbc_raw(&k1, iv).map_err(|e| {
1719 crate::error::PdfError::EncryptionError(format!(
1720 "Algorithm 2.B: AES encryption failed: {}",
1721 e
1722 ))
1723 })?;
1724
1725 let hash_selector = {
1730 let sum: u64 = e[..HASH_SELECTOR_BYTES.min(e.len())]
1731 .iter()
1732 .map(|&b| b as u64)
1733 .sum();
1734 (sum % 3) as u8
1735 };
1736
1737 k = match hash_selector {
1738 0 => sha256(&e),
1739 1 => sha384(&e),
1740 2 => sha512(&e),
1741 _ => unreachable!("Modulo 3 can only be 0, 1, or 2"),
1742 };
1743
1744 let last_byte = *e.last().unwrap_or(&0);
1747 round += 1;
1748
1749 if round >= ALGORITHM_2B_MIN_ROUNDS {
1750 if (last_byte as usize) <= round.saturating_sub(32) {
1754 break;
1755 }
1756 }
1757
1758 if round >= ALGORITHM_2B_MAX_ROUNDS {
1760 break;
1761 }
1762 }
1763
1764 Ok(k[..32.min(k.len())].to_vec())
1767}
1768
1769const R5_SALT_LENGTH: usize = 8;
1771
1772const R5_HASH_ITERATIONS: usize = 0;
1776
1777const R6_SALT_LENGTH: usize = 8;
1779
1780const U_HASH_LENGTH: usize = 32;
1786
1787const U_VALIDATION_SALT_START: usize = 32;
1789
1790const U_VALIDATION_SALT_END: usize = 40;
1792
1793const U_KEY_SALT_START: usize = 40;
1795
1796const U_KEY_SALT_END: usize = 48;
1798
1799const U_ENTRY_LENGTH: usize = 48;
1801
1802const UE_ENTRY_LENGTH: usize = 32;
1804
1805const PERMS_ENTRY_LENGTH: usize = 16;
1811
1812const PERMS_P_START: usize = 0;
1814
1815const PERMS_P_END: usize = 4;
1817
1818const PERMS_MARKER_START: usize = 4;
1820
1821const PERMS_MARKER_END: usize = 8;
1823
1824const PERMS_LITERAL_START: usize = 8;
1826
1827const PERMS_LITERAL_END: usize = 11;
1829
1830const PERMS_ENCRYPT_META_BYTE: usize = 11;
1832
1833const PERMS_MARKER: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];
1835
1836const PERMS_LITERAL: &[u8; 3] = b"adb";
1838
1839fn generate_salt(len: usize) -> Vec<u8> {
1849 let mut salt = vec![0u8; len];
1850 rand::rng().fill_bytes(&mut salt);
1851 salt
1852}
1853
1854#[cfg(test)]
1855mod tests {
1856 use super::*;
1857
1858 #[test]
1859 fn test_pad_password() {
1860 let padded = StandardSecurityHandler::pad_password("test");
1861 assert_eq!(padded.len(), 32);
1862 assert_eq!(&padded[..4], b"test");
1863 assert_eq!(&padded[4..8], &PADDING[..4]);
1864 }
1865
1866 #[test]
1867 fn test_pad_password_long() {
1868 let long_password = "a".repeat(40);
1869 let padded = StandardSecurityHandler::pad_password(&long_password);
1870 assert_eq!(padded.len(), 32);
1871 assert_eq!(&padded[..32], &long_password.as_bytes()[..32]);
1872 }
1873
1874 #[test]
1875 fn test_rc4_40bit_handler() {
1876 let handler = StandardSecurityHandler::rc4_40bit();
1877 assert_eq!(handler.revision, SecurityHandlerRevision::R2);
1878 assert_eq!(handler.key_length, 5);
1879 }
1880
1881 #[test]
1882 fn test_rc4_128bit_handler() {
1883 let handler = StandardSecurityHandler::rc4_128bit();
1884 assert_eq!(handler.revision, SecurityHandlerRevision::R3);
1885 assert_eq!(handler.key_length, 16);
1886 }
1887
1888 #[test]
1889 fn test_owner_hash_computation() {
1890 let handler = StandardSecurityHandler::rc4_40bit();
1891 let owner_pwd = OwnerPassword("owner".to_string());
1892 let user_pwd = UserPassword("user".to_string());
1893
1894 let hash = handler.compute_owner_hash(&owner_pwd, &user_pwd);
1895 assert_eq!(hash.len(), 32);
1896 }
1897
1898 #[test]
1899 fn test_encryption_key_computation() {
1900 let handler = StandardSecurityHandler::rc4_40bit();
1901 let user_pwd = UserPassword("user".to_string());
1902 let owner_hash = vec![0u8; 32];
1903 let permissions = Permissions::new();
1904
1905 let key = handler
1906 .compute_encryption_key(&user_pwd, &owner_hash, permissions, None)
1907 .unwrap();
1908
1909 assert_eq!(key.len(), 5);
1910 }
1911
1912 #[test]
1913 fn test_aes_256_r5_handler() {
1914 let handler = StandardSecurityHandler::aes_256_r5();
1915 assert_eq!(handler.revision, SecurityHandlerRevision::R5);
1916 assert_eq!(handler.key_length, 32);
1917 }
1918
1919 #[test]
1920 fn test_aes_256_r6_handler() {
1921 let handler = StandardSecurityHandler::aes_256_r6();
1922 assert_eq!(handler.revision, SecurityHandlerRevision::R6);
1923 assert_eq!(handler.key_length, 32);
1924 }
1925
1926 #[test]
1927 fn test_aes_encryption_key_computation() {
1928 let handler = StandardSecurityHandler::aes_256_r5();
1929 let user_pwd = UserPassword("testuser".to_string());
1930 let owner_hash = vec![0u8; 32];
1931 let permissions = Permissions::new();
1932
1933 let key = handler
1934 .compute_aes_encryption_key(&user_pwd, &owner_hash, permissions, None)
1935 .unwrap();
1936
1937 assert_eq!(key.len(), 32);
1938 }
1939
1940 #[test]
1941 fn test_aes_encrypt_decrypt() {
1942 let handler = StandardSecurityHandler::aes_256_r5();
1943 let key = EncryptionKey::new(vec![0u8; 32]);
1944 let obj_id = ObjectId::new(1, 0);
1945 let data = b"Hello AES encryption!";
1946
1947 let encrypted = handler.encrypt_aes(data, &key, &obj_id).unwrap();
1948 assert_ne!(encrypted.as_slice(), data);
1949 assert!(encrypted.len() > data.len()); let _decrypted = handler.decrypt_aes(&encrypted, &key, &obj_id);
1953 }
1955
1956 #[test]
1957 fn test_aes_with_rc4_handler_fails() {
1958 let handler = StandardSecurityHandler::rc4_128bit();
1959 let key = EncryptionKey::new(vec![0u8; 16]);
1960 let obj_id = ObjectId::new(1, 0);
1961 let data = b"test data";
1962
1963 assert!(handler.encrypt_aes(data, &key, &obj_id).is_err());
1965 assert!(handler.decrypt_aes(data, &key, &obj_id).is_err());
1966 }
1967
1968 #[test]
1969 fn test_aes_decrypt_invalid_data() {
1970 let handler = StandardSecurityHandler::aes_256_r5();
1971 let key = EncryptionKey::new(vec![0u8; 32]);
1972 let obj_id = ObjectId::new(1, 0);
1973
1974 let short_data = vec![0u8; 10];
1976 assert!(handler.decrypt_aes(&short_data, &key, &obj_id).is_err());
1977 }
1978
1979 #[test]
1980 fn test_sha256_deterministic() {
1981 let data1 = b"test data";
1982 let data2 = b"test data";
1983 let data3 = b"different data";
1984
1985 let hash1 = sha256(data1);
1986 let hash2 = sha256(data2);
1987 let hash3 = sha256(data3);
1988
1989 assert_eq!(hash1.len(), 32);
1990 assert_eq!(hash2.len(), 32);
1991 assert_eq!(hash3.len(), 32);
1992
1993 assert_eq!(hash1, hash2); assert_ne!(hash1, hash3); }
1996
1997 #[test]
1998 fn test_security_handler_revision_ordering() {
1999 assert!(SecurityHandlerRevision::R2 < SecurityHandlerRevision::R3);
2000 assert!(SecurityHandlerRevision::R3 < SecurityHandlerRevision::R4);
2001 assert!(SecurityHandlerRevision::R4 < SecurityHandlerRevision::R5);
2002 assert!(SecurityHandlerRevision::R5 < SecurityHandlerRevision::R6);
2003 }
2004
2005 #[test]
2006 fn test_aes_password_validation() {
2007 let handler = StandardSecurityHandler::aes_256_r5();
2008 let password = UserPassword("testpassword".to_string());
2009 let user_hash = vec![0u8; 32]; let permissions = Permissions::new();
2011
2012 let result = handler.validate_aes_user_password(&password, &user_hash, permissions, None);
2014 assert!(result.is_ok());
2015 }
2016
2017 #[test]
2020 fn test_user_password_debug() {
2021 let pwd = UserPassword("debug_test".to_string());
2022 let debug_str = format!("{pwd:?}");
2023 assert!(debug_str.contains("UserPassword"));
2024 assert!(debug_str.contains("debug_test"));
2025 }
2026
2027 #[test]
2028 fn test_owner_password_debug() {
2029 let pwd = OwnerPassword("owner_debug".to_string());
2030 let debug_str = format!("{pwd:?}");
2031 assert!(debug_str.contains("OwnerPassword"));
2032 assert!(debug_str.contains("owner_debug"));
2033 }
2034
2035 #[test]
2036 fn test_encryption_key_debug() {
2037 let key = EncryptionKey::new(vec![0x01, 0x02, 0x03]);
2038 let debug_str = format!("{key:?}");
2039 assert!(debug_str.contains("EncryptionKey"));
2040 }
2041
2042 #[test]
2043 fn test_security_handler_revision_equality() {
2044 assert_eq!(SecurityHandlerRevision::R2, SecurityHandlerRevision::R2);
2045 assert_ne!(SecurityHandlerRevision::R2, SecurityHandlerRevision::R3);
2046 }
2047
2048 #[test]
2049 fn test_security_handler_revision_values() {
2050 assert_eq!(SecurityHandlerRevision::R2 as u8, 2);
2051 assert_eq!(SecurityHandlerRevision::R3 as u8, 3);
2052 assert_eq!(SecurityHandlerRevision::R4 as u8, 4);
2053 assert_eq!(SecurityHandlerRevision::R5 as u8, 5);
2054 assert_eq!(SecurityHandlerRevision::R6 as u8, 6);
2055 }
2056
2057 #[test]
2058 fn test_pad_password_various_lengths() {
2059 for len in 0..=40 {
2060 let password = "x".repeat(len);
2061 let padded = StandardSecurityHandler::pad_password(&password);
2062 assert_eq!(padded.len(), 32);
2063
2064 if len <= 32 {
2065 assert_eq!(&padded[..len], password.as_bytes());
2066 } else {
2067 assert_eq!(&padded[..], &password.as_bytes()[..32]);
2068 }
2069 }
2070 }
2071
2072 #[test]
2073 fn test_pad_password_unicode() {
2074 let padded = StandardSecurityHandler::pad_password("café");
2075 assert_eq!(padded.len(), 32);
2076 assert_eq!(&padded[..5], "café".as_bytes());
2078 }
2079
2080 #[test]
2081 fn test_compute_owner_hash_different_users() {
2082 let handler = StandardSecurityHandler::rc4_128bit();
2083 let owner = OwnerPassword("owner".to_string());
2084 let user1 = UserPassword("user1".to_string());
2085 let user2 = UserPassword("user2".to_string());
2086
2087 let hash1 = handler.compute_owner_hash(&owner, &user1);
2088 let hash2 = handler.compute_owner_hash(&owner, &user2);
2089
2090 assert_ne!(hash1, hash2); }
2092
2093 #[test]
2094 fn test_compute_user_hash_r4() {
2095 let handler = StandardSecurityHandler {
2096 revision: SecurityHandlerRevision::R4,
2097 key_length: 16,
2098 };
2099 let user = UserPassword("r4test".to_string());
2100 let owner_hash = vec![0xAA; 32];
2101 let permissions = Permissions::new();
2102
2103 let hash = handler
2104 .compute_user_hash(&user, &owner_hash, permissions, None)
2105 .unwrap();
2106 assert_eq!(hash.len(), 32);
2107 }
2108
2109 #[test]
2110 fn test_compute_user_hash_r6() {
2111 let handler = StandardSecurityHandler::aes_256_r6();
2112 let user = UserPassword("r6test".to_string());
2113 let owner_hash = vec![0xBB; 32];
2114 let permissions = Permissions::all();
2115
2116 let hash = handler
2117 .compute_user_hash(&user, &owner_hash, permissions, None)
2118 .unwrap();
2119 assert_eq!(hash.len(), 32);
2120 }
2121
2122 #[test]
2123 fn test_encryption_key_with_file_id_affects_result() {
2124 let handler = StandardSecurityHandler::rc4_128bit();
2125 let user = UserPassword("test".to_string());
2126 let owner_hash = vec![0xFF; 32];
2127 let permissions = Permissions::new();
2128 let file_id = b"unique_file_id_12345";
2129
2130 let key_with_id = handler
2131 .compute_encryption_key(&user, &owner_hash, permissions, Some(file_id))
2132 .unwrap();
2133 let key_without_id = handler
2134 .compute_encryption_key(&user, &owner_hash, permissions, None)
2135 .unwrap();
2136
2137 assert_ne!(key_with_id.key, key_without_id.key);
2138 }
2139
2140 #[test]
2141 fn test_encrypt_string_empty() {
2142 let handler = StandardSecurityHandler::rc4_40bit();
2143 let key = EncryptionKey::new(vec![0x01, 0x02, 0x03, 0x04, 0x05]);
2144 let obj_id = ObjectId::new(1, 0);
2145
2146 let encrypted = handler.encrypt_string(b"", &key, &obj_id);
2147 assert_eq!(encrypted.len(), 0);
2148 }
2149
2150 #[test]
2151 fn test_encrypt_decrypt_large_data() {
2152 let handler = StandardSecurityHandler::rc4_128bit();
2153 let key = EncryptionKey::new(vec![0xAA; 16]);
2154 let obj_id = ObjectId::new(42, 0);
2155 let large_data = vec![0x55; 10000]; let encrypted = handler.encrypt_string(&large_data, &key, &obj_id);
2158 assert_eq!(encrypted.len(), large_data.len());
2159 assert_ne!(encrypted, large_data);
2160
2161 let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id);
2162 assert_eq!(decrypted, large_data);
2163 }
2164
2165 #[test]
2166 fn test_stream_encryption_different_from_string() {
2167 let handler = StandardSecurityHandler::rc4_128bit();
2169 let key = EncryptionKey::new(vec![0x11; 16]);
2170 let obj_id = ObjectId::new(5, 1);
2171 let data = b"Stream content test";
2172
2173 let encrypted_string = handler.encrypt_string(data, &key, &obj_id);
2174 let encrypted_stream = handler.encrypt_stream(data, &key, &obj_id);
2175
2176 assert_eq!(encrypted_string, encrypted_stream); }
2178
2179 #[test]
2180 fn test_aes_encryption_with_different_object_ids() {
2181 let handler = StandardSecurityHandler::aes_256_r5();
2182 let key = EncryptionKey::new(vec![0x77; 32]);
2183 let obj_id1 = ObjectId::new(10, 0);
2184 let obj_id2 = ObjectId::new(11, 0);
2185 let data = b"AES test data";
2186
2187 let encrypted1 = handler.encrypt_aes(data, &key, &obj_id1).unwrap();
2188 let encrypted2 = handler.encrypt_aes(data, &key, &obj_id2).unwrap();
2189
2190 assert_ne!(encrypted1, encrypted2);
2192 }
2193
2194 #[test]
2195 fn test_aes_decrypt_invalid_iv_length() {
2196 let handler = StandardSecurityHandler::aes_256_r5();
2197 let key = EncryptionKey::new(vec![0x88; 32]);
2198 let obj_id = ObjectId::new(1, 0);
2199
2200 let short_data = vec![0u8; 10];
2202 assert!(handler.decrypt_aes(&short_data, &key, &obj_id).is_err());
2203
2204 let iv_only = vec![0u8; 16];
2206 let result = handler.decrypt_aes(&iv_only, &key, &obj_id);
2207 if let Ok(decrypted) = result {
2209 assert_eq!(decrypted.len(), 0);
2210 }
2211 }
2212
2213 #[test]
2214 fn test_aes_validate_password_wrong_hash_length() {
2215 let handler = StandardSecurityHandler::aes_256_r5();
2216 let password = UserPassword("test".to_string());
2217 let short_hash = vec![0u8; 16]; let permissions = Permissions::new();
2219
2220 let result = handler
2221 .validate_aes_user_password(&password, &short_hash, permissions, None)
2222 .unwrap();
2223 assert!(!result); }
2225
2226 #[test]
2227 fn test_permissions_affect_encryption_key() {
2228 let handler = StandardSecurityHandler::rc4_128bit();
2229 let user = UserPassword("same_user".to_string());
2230 let owner_hash = vec![0xCC; 32];
2231
2232 let perms1 = Permissions::new();
2233 let perms2 = Permissions::all();
2234
2235 let key1 = handler
2236 .compute_encryption_key(&user, &owner_hash, perms1, None)
2237 .unwrap();
2238 let key2 = handler
2239 .compute_encryption_key(&user, &owner_hash, perms2, None)
2240 .unwrap();
2241
2242 assert_ne!(key1.key, key2.key); }
2244
2245 #[test]
2246 fn test_different_handlers_produce_different_keys() {
2247 let user = UserPassword("test".to_string());
2248 let owner_hash = vec![0xDD; 32];
2249 let permissions = Permissions::new();
2250
2251 let handler_r2 = StandardSecurityHandler::rc4_40bit();
2252 let handler_r3 = StandardSecurityHandler::rc4_128bit();
2253
2254 let key_r2 = handler_r2
2255 .compute_encryption_key(&user, &owner_hash, permissions, None)
2256 .unwrap();
2257 let key_r3 = handler_r3
2258 .compute_encryption_key(&user, &owner_hash, permissions, None)
2259 .unwrap();
2260
2261 assert_ne!(key_r2.len(), key_r3.len()); assert_eq!(key_r2.len(), 5);
2263 assert_eq!(key_r3.len(), 16);
2264 }
2265
2266 #[test]
2267 fn test_full_workflow_aes_r6() {
2268 let handler = StandardSecurityHandler::aes_256_r6();
2269 let user_pwd = UserPassword("user_r6".to_string());
2270 let permissions = Permissions::new();
2271 let file_id = b"test_file_r6";
2272
2273 let owner_hash = vec![0x42; 32]; let user_hash = handler
2278 .compute_user_hash(&user_pwd, &owner_hash, permissions, Some(file_id))
2279 .unwrap();
2280 assert_eq!(user_hash.len(), 32);
2281
2282 let key = handler
2284 .compute_aes_encryption_key(&user_pwd, &owner_hash, permissions, Some(file_id))
2285 .unwrap();
2286 assert_eq!(key.len(), 32);
2287
2288 let obj_id = ObjectId::new(100, 5);
2290 let content = b"R6 AES encryption test";
2291 let encrypted = handler.encrypt_string(content, &key, &obj_id);
2292
2293 if !encrypted.is_empty() {
2295 assert_ne!(encrypted.as_slice(), content);
2296 }
2297 }
2298
2299 #[test]
2300 fn test_md5_compute_consistency() {
2301 let data = b"consistent data for md5";
2302 let hash1 = md5::compute(data);
2303 let hash2 = md5::compute(data);
2304
2305 assert_eq!(hash1, hash2);
2306 assert_eq!(hash1.len(), 16);
2307 }
2308
2309 #[test]
2310 fn test_sha256_consistency() {
2311 let data = b"consistent data for sha256";
2312 let hash1 = sha256(data);
2313 let hash2 = sha256(data);
2314
2315 assert_eq!(hash1, hash2);
2316 assert_eq!(hash1.len(), 32);
2317 }
2318
2319 #[test]
2320 fn test_rc4_encrypt_helper() {
2321 let key = Rc4Key::from_slice(&[0x01, 0x02, 0x03, 0x04, 0x05]);
2322 let data = b"test rc4 helper";
2323
2324 let encrypted = rc4_encrypt(&key, data);
2325 assert_ne!(encrypted.as_slice(), data);
2326
2327 let decrypted = rc4_encrypt(&key, &encrypted);
2329 assert_eq!(decrypted.as_slice(), data);
2330 }
2331
2332 #[test]
2333 fn test_edge_case_max_object_generation() {
2334 let handler = StandardSecurityHandler::rc4_128bit();
2335 let key = EncryptionKey::new(vec![0xEE; 16]);
2336 let obj_id = ObjectId::new(0xFFFFFF, 0xFFFF); let data = b"edge case";
2338
2339 let encrypted = handler.encrypt_string(data, &key, &obj_id);
2340 let decrypted = handler.decrypt_string(&encrypted, &key, &obj_id);
2341 assert_eq!(decrypted.as_slice(), data);
2342 }
2343
2344 #[test]
2347 fn test_sha256_nist_empty_string() {
2348 let hash = sha256(b"");
2350 let expected: [u8; 32] = [
2351 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f,
2352 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
2353 0x78, 0x52, 0xb8, 0x55,
2354 ];
2355 assert_eq!(
2356 hash.as_slice(),
2357 expected.as_slice(),
2358 "SHA-256('') must match NIST test vector"
2359 );
2360 }
2361
2362 #[test]
2363 fn test_sha256_nist_abc() {
2364 let hash = sha256(b"abc");
2366 let expected: [u8; 32] = [
2367 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
2368 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
2369 0xf2, 0x00, 0x15, 0xad,
2370 ];
2371 assert_eq!(
2372 hash.as_slice(),
2373 expected.as_slice(),
2374 "SHA-256('abc') must match NIST test vector"
2375 );
2376 }
2377
2378 #[test]
2379 fn test_sha512_nist_abc() {
2380 let hash = sha512(b"abc");
2382 let expected: [u8; 64] = [
2383 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20,
2384 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6,
2385 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba,
2386 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
2387 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
2388 ];
2389 assert_eq!(
2390 hash.as_slice(),
2391 expected.as_slice(),
2392 "SHA-512('abc') must match NIST test vector"
2393 );
2394 }
2395
2396 #[test]
2397 fn test_sha512_length() {
2398 let hash = sha512(b"test data");
2399 assert_eq!(hash.len(), 64, "SHA-512 must produce 64 bytes");
2400 }
2401
2402 #[test]
2403 fn test_sha512_deterministic() {
2404 let data1 = b"sha512 test data";
2405 let data2 = b"sha512 test data";
2406 let data3 = b"different data";
2407
2408 let hash1 = sha512(data1);
2409 let hash2 = sha512(data2);
2410 let hash3 = sha512(data3);
2411
2412 assert_eq!(hash1, hash2, "Same input must produce same SHA-512 hash");
2413 assert_ne!(hash1, hash3, "Different input must produce different hash");
2414 }
2415
2416 #[test]
2419 fn test_r5_user_hash_computation() {
2420 let handler = StandardSecurityHandler::aes_256_r5();
2421 let password = UserPassword("test_password".to_string());
2422
2423 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2424
2425 assert_eq!(u_entry.len(), 48, "R5 U entry must be 48 bytes");
2427 }
2428
2429 #[test]
2430 fn test_r5_user_password_validation_correct() {
2431 let handler = StandardSecurityHandler::aes_256_r5();
2432 let password = UserPassword("correct_password".to_string());
2433
2434 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2436
2437 let is_valid = handler
2439 .validate_r5_user_password(&password, &u_entry)
2440 .unwrap();
2441 assert!(is_valid, "Correct password must validate");
2442 }
2443
2444 #[test]
2445 fn test_r5_user_password_validation_incorrect() {
2446 let handler = StandardSecurityHandler::aes_256_r5();
2447 let correct_password = UserPassword("correct_password".to_string());
2448 let wrong_password = UserPassword("wrong_password".to_string());
2449
2450 let u_entry = handler.compute_r5_user_hash(&correct_password).unwrap();
2452
2453 let is_valid = handler
2455 .validate_r5_user_password(&wrong_password, &u_entry)
2456 .unwrap();
2457 assert!(!is_valid, "Wrong password must not validate");
2458 }
2459
2460 #[test]
2461 fn test_r5_user_hash_random_salts() {
2462 let handler = StandardSecurityHandler::aes_256_r5();
2463 let password = UserPassword("same_password".to_string());
2464
2465 let u_entry1 = handler.compute_r5_user_hash(&password).unwrap();
2467 let u_entry2 = handler.compute_r5_user_hash(&password).unwrap();
2468
2469 assert_ne!(
2471 &u_entry1[..32],
2472 &u_entry2[..32],
2473 "Different random salts should produce different hashes"
2474 );
2475
2476 assert_ne!(
2478 &u_entry1[32..40],
2479 &u_entry2[32..40],
2480 "Validation salts must be random"
2481 );
2482
2483 assert!(handler
2485 .validate_r5_user_password(&password, &u_entry1)
2486 .unwrap());
2487 assert!(handler
2488 .validate_r5_user_password(&password, &u_entry2)
2489 .unwrap());
2490 }
2491
2492 #[test]
2493 fn test_r5_user_hash_invalid_entry_length() {
2494 let handler = StandardSecurityHandler::aes_256_r5();
2495 let password = UserPassword("test".to_string());
2496
2497 let short_entry = vec![0u8; 32]; let result = handler.validate_r5_user_password(&password, &short_entry);
2500 assert!(result.is_err(), "Short U entry must fail");
2501
2502 let long_entry = vec![0u8; 64]; let result = handler.validate_r5_user_password(&password, &long_entry);
2504 assert!(result.is_err(), "Long U entry must fail");
2505 }
2506
2507 #[test]
2508 fn test_r5_empty_password() {
2509 let handler = StandardSecurityHandler::aes_256_r5();
2510 let empty_password = UserPassword("".to_string());
2511
2512 let u_entry = handler.compute_r5_user_hash(&empty_password).unwrap();
2514 assert_eq!(u_entry.len(), 48);
2515
2516 let is_valid = handler
2517 .validate_r5_user_password(&empty_password, &u_entry)
2518 .unwrap();
2519 assert!(is_valid, "Empty password must validate correctly");
2520
2521 let non_empty = UserPassword("not_empty".to_string());
2523 let is_valid = handler
2524 .validate_r5_user_password(&non_empty, &u_entry)
2525 .unwrap();
2526 assert!(!is_valid, "Non-empty password must not validate");
2527 }
2528
2529 #[test]
2532 fn test_r5_ue_entry_computation() {
2533 let handler = StandardSecurityHandler::aes_256_r5();
2534 let password = UserPassword("ue_test_password".to_string());
2535 let encryption_key = EncryptionKey::new(vec![0xAB; 32]);
2536
2537 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2539
2540 let ue_entry = handler
2542 .compute_r5_ue_entry(&password, &u_entry, &encryption_key)
2543 .unwrap();
2544
2545 assert_eq!(ue_entry.len(), 32, "R5 UE entry must be 32 bytes");
2547
2548 assert_ne!(
2550 ue_entry.as_slice(),
2551 encryption_key.as_bytes(),
2552 "UE must be encrypted"
2553 );
2554 }
2555
2556 #[test]
2557 fn test_r5_encryption_key_recovery() {
2558 let handler = StandardSecurityHandler::aes_256_r5();
2559 let password = UserPassword("recovery_test".to_string());
2560 let original_key = EncryptionKey::new(vec![0x42; 32]);
2561
2562 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2564
2565 let ue_entry = handler
2567 .compute_r5_ue_entry(&password, &u_entry, &original_key)
2568 .unwrap();
2569
2570 let recovered_key = handler
2572 .recover_r5_encryption_key(&password, &u_entry, &ue_entry)
2573 .unwrap();
2574
2575 assert_eq!(
2577 recovered_key.as_bytes(),
2578 original_key.as_bytes(),
2579 "Recovered key must match original"
2580 );
2581 }
2582
2583 #[test]
2584 fn test_r5_ue_wrong_password_fails() {
2585 let handler = StandardSecurityHandler::aes_256_r5();
2586 let correct_password = UserPassword("correct".to_string());
2587 let wrong_password = UserPassword("wrong".to_string());
2588 let original_key = EncryptionKey::new(vec![0x99; 32]);
2589
2590 let u_entry = handler.compute_r5_user_hash(&correct_password).unwrap();
2592 let ue_entry = handler
2593 .compute_r5_ue_entry(&correct_password, &u_entry, &original_key)
2594 .unwrap();
2595
2596 let recovered_key = handler
2598 .recover_r5_encryption_key(&wrong_password, &u_entry, &ue_entry)
2599 .unwrap();
2600
2601 assert_ne!(
2603 recovered_key.as_bytes(),
2604 original_key.as_bytes(),
2605 "Wrong password must produce wrong key"
2606 );
2607 }
2608
2609 #[test]
2610 fn test_r5_ue_invalid_length() {
2611 let handler = StandardSecurityHandler::aes_256_r5();
2612 let password = UserPassword("test".to_string());
2613 let u_entry = vec![0u8; 48]; let short_ue = vec![0u8; 16]; let result = handler.recover_r5_encryption_key(&password, &u_entry, &short_ue);
2618 assert!(result.is_err(), "Short UE entry must fail");
2619
2620 let long_ue = vec![0u8; 64]; let result = handler.recover_r5_encryption_key(&password, &u_entry, &long_ue);
2622 assert!(result.is_err(), "Long UE entry must fail");
2623 }
2624
2625 #[test]
2626 fn test_r5_ue_invalid_u_length() {
2627 let handler = StandardSecurityHandler::aes_256_r5();
2628 let password = UserPassword("test".to_string());
2629 let encryption_key = EncryptionKey::new(vec![0x11; 32]);
2630
2631 let short_u = vec![0u8; 32]; let result = handler.compute_r5_ue_entry(&password, &short_u, &encryption_key);
2634 assert!(
2635 result.is_err(),
2636 "Short U entry must fail for UE computation"
2637 );
2638 }
2639
2640 #[test]
2641 fn test_r5_full_workflow_u_ue() {
2642 let handler = StandardSecurityHandler::aes_256_r5();
2643 let password = UserPassword("full_workflow_test".to_string());
2644 let encryption_key = EncryptionKey::new((0..32).collect::<Vec<u8>>());
2645
2646 let u_entry = handler.compute_r5_user_hash(&password).unwrap();
2648 assert_eq!(u_entry.len(), 48);
2649
2650 assert!(handler
2652 .validate_r5_user_password(&password, &u_entry)
2653 .unwrap());
2654
2655 let ue_entry = handler
2657 .compute_r5_ue_entry(&password, &u_entry, &encryption_key)
2658 .unwrap();
2659 assert_eq!(ue_entry.len(), 32);
2660
2661 let recovered = handler
2663 .recover_r5_encryption_key(&password, &u_entry, &ue_entry)
2664 .unwrap();
2665
2666 assert_eq!(
2668 recovered.as_bytes(),
2669 encryption_key.as_bytes(),
2670 "Full R5 workflow: recovered key must match original"
2671 );
2672 }
2673
2674 #[test]
2677 fn test_r6_user_hash_computation() {
2678 let handler = StandardSecurityHandler::aes_256_r6();
2679 let password = UserPassword("r6_test_password".to_string());
2680
2681 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2682
2683 assert_eq!(u_entry.len(), 48, "R6 U entry must be 48 bytes");
2685 }
2686
2687 #[test]
2688 fn test_r6_user_password_validation_correct() {
2689 let handler = StandardSecurityHandler::aes_256_r6();
2690 let password = UserPassword("r6_correct_password".to_string());
2691
2692 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2694
2695 let is_valid = handler
2697 .validate_r6_user_password(&password, &u_entry)
2698 .unwrap();
2699 assert!(is_valid, "Correct R6 password must validate");
2700 }
2701
2702 #[test]
2703 fn test_r6_user_password_validation_incorrect() {
2704 let handler = StandardSecurityHandler::aes_256_r6();
2705 let correct_password = UserPassword("r6_correct".to_string());
2706 let wrong_password = UserPassword("r6_wrong".to_string());
2707
2708 let u_entry = handler.compute_r6_user_hash(&correct_password).unwrap();
2710
2711 let is_valid = handler
2713 .validate_r6_user_password(&wrong_password, &u_entry)
2714 .unwrap();
2715 assert!(!is_valid, "Wrong R6 password must not validate");
2716 }
2717
2718 #[test]
2719 fn test_r6_uses_sha512_not_sha256() {
2720 let handler_r5 = StandardSecurityHandler::aes_256_r5();
2722 let handler_r6 = StandardSecurityHandler::aes_256_r6();
2723 let password = UserPassword("same_password_both_revisions".to_string());
2724
2725 let u_r5 = handler_r5.compute_r5_user_hash(&password).unwrap();
2726 let u_r6 = handler_r6.compute_r6_user_hash(&password).unwrap();
2727
2728 assert_ne!(
2731 &u_r5[..32],
2732 &u_r6[..32],
2733 "R5 (SHA-256) and R6 (SHA-512) must produce different hashes"
2734 );
2735 }
2736
2737 #[test]
2738 fn test_r6_unicode_password() {
2739 let handler = StandardSecurityHandler::aes_256_r6();
2740 let unicode_password = UserPassword("café🔒日本語".to_string());
2741
2742 let u_entry = handler.compute_r6_user_hash(&unicode_password).unwrap();
2743 assert_eq!(u_entry.len(), 48);
2744
2745 let is_valid = handler
2747 .validate_r6_user_password(&unicode_password, &u_entry)
2748 .unwrap();
2749 assert!(is_valid, "Unicode password must validate");
2750
2751 let different_unicode = UserPassword("café🔓日本語".to_string()); let is_valid = handler
2754 .validate_r6_user_password(&different_unicode, &u_entry)
2755 .unwrap();
2756 assert!(!is_valid, "Different Unicode password must not validate");
2757 }
2758
2759 #[test]
2762 fn test_r6_ue_entry_computation() {
2763 let handler = StandardSecurityHandler::aes_256_r6();
2764 let password = UserPassword("r6_ue_test".to_string());
2765 let encryption_key = EncryptionKey::new(vec![0xCD; 32]);
2766
2767 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2768 let ue_entry = handler
2769 .compute_r6_ue_entry(&password, &u_entry, &encryption_key)
2770 .unwrap();
2771
2772 assert_eq!(ue_entry.len(), 32, "R6 UE entry must be 32 bytes");
2773 }
2774
2775 #[test]
2776 fn test_r6_encryption_key_recovery() {
2777 let handler = StandardSecurityHandler::aes_256_r6();
2778 let password = UserPassword("r6_recovery_test".to_string());
2779 let original_key = EncryptionKey::new(vec![0xEF; 32]);
2780
2781 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2782 let ue_entry = handler
2783 .compute_r6_ue_entry(&password, &u_entry, &original_key)
2784 .unwrap();
2785
2786 let recovered_key = handler
2787 .recover_r6_encryption_key(&password, &u_entry, &ue_entry)
2788 .unwrap();
2789
2790 assert_eq!(
2791 recovered_key.as_bytes(),
2792 original_key.as_bytes(),
2793 "R6: Recovered key must match original"
2794 );
2795 }
2796
2797 #[test]
2800 fn test_r6_perms_entry_computation() {
2801 let handler = StandardSecurityHandler::aes_256_r6();
2802 let permissions = Permissions::all();
2803 let key = EncryptionKey::new(vec![0x42; 32]);
2804
2805 let perms = handler
2806 .compute_r6_perms_entry(permissions, &key, true)
2807 .unwrap();
2808
2809 assert_eq!(perms.len(), 16, "Perms entry must be 16 bytes");
2810 }
2811
2812 #[test]
2813 fn test_r6_perms_validation() {
2814 let handler = StandardSecurityHandler::aes_256_r6();
2815 let permissions = Permissions::new();
2816 let key = EncryptionKey::new(vec![0x55; 32]);
2817
2818 let perms = handler
2819 .compute_r6_perms_entry(permissions, &key, false)
2820 .unwrap();
2821
2822 let is_valid = handler
2823 .validate_r6_perms(&perms, &key, permissions)
2824 .unwrap();
2825 assert!(is_valid, "Perms validation must succeed with correct key");
2826 }
2827
2828 #[test]
2829 fn test_r6_perms_wrong_key_fails() {
2830 let handler = StandardSecurityHandler::aes_256_r6();
2831 let permissions = Permissions::all();
2832 let correct_key = EncryptionKey::new(vec![0xAA; 32]);
2833 let wrong_key = EncryptionKey::new(vec![0xBB; 32]);
2834
2835 let perms = handler
2836 .compute_r6_perms_entry(permissions, &correct_key, true)
2837 .unwrap();
2838
2839 let result = handler.validate_r6_perms(&perms, &wrong_key, permissions);
2841 assert!(result.is_ok()); assert!(!result.unwrap()); }
2844
2845 #[test]
2846 fn test_r6_perms_encrypt_metadata_flag() {
2847 let handler = StandardSecurityHandler::aes_256_r6();
2848 let permissions = Permissions::new();
2849 let key = EncryptionKey::new(vec![0x33; 32]);
2850
2851 let perms_true = handler
2852 .compute_r6_perms_entry(permissions, &key, true)
2853 .unwrap();
2854 let perms_false = handler
2855 .compute_r6_perms_entry(permissions, &key, false)
2856 .unwrap();
2857
2858 assert_ne!(
2860 perms_true, perms_false,
2861 "Different EncryptMetadata must produce different Perms"
2862 );
2863
2864 let flag_true = handler
2866 .extract_r6_encrypt_metadata(&perms_true, &key)
2867 .unwrap();
2868 assert_eq!(flag_true, Some(true));
2869
2870 let flag_false = handler
2871 .extract_r6_encrypt_metadata(&perms_false, &key)
2872 .unwrap();
2873 assert_eq!(flag_false, Some(false));
2874 }
2875
2876 #[test]
2877 fn test_r6_perms_invalid_length() {
2878 let handler = StandardSecurityHandler::aes_256_r6();
2879 let key = EncryptionKey::new(vec![0x44; 32]);
2880 let permissions = Permissions::new();
2881
2882 let invalid_perms = vec![0u8; 12]; let result = handler.validate_r6_perms(&invalid_perms, &key, permissions);
2884 assert!(result.is_err(), "Short Perms entry must fail");
2885 }
2886
2887 #[test]
2888 fn test_r6_full_workflow_with_perms() {
2889 let handler = StandardSecurityHandler::aes_256_r6();
2891 let password = UserPassword("r6_full_workflow".to_string());
2892 let permissions = Permissions::all();
2893 let encryption_key = EncryptionKey::new((0..32).map(|i| (i * 3) as u8).collect());
2894
2895 let u_entry = handler.compute_r6_user_hash(&password).unwrap();
2897 assert_eq!(u_entry.len(), 48);
2898
2899 assert!(handler
2901 .validate_r6_user_password(&password, &u_entry)
2902 .unwrap());
2903
2904 let ue_entry = handler
2906 .compute_r6_ue_entry(&password, &u_entry, &encryption_key)
2907 .unwrap();
2908 assert_eq!(ue_entry.len(), 32);
2909
2910 let perms = handler
2912 .compute_r6_perms_entry(permissions, &encryption_key, true)
2913 .unwrap();
2914 assert_eq!(perms.len(), 16);
2915
2916 let recovered_key = handler
2918 .recover_r6_encryption_key(&password, &u_entry, &ue_entry)
2919 .unwrap();
2920 assert_eq!(
2921 recovered_key.as_bytes(),
2922 encryption_key.as_bytes(),
2923 "Recovered key must match original"
2924 );
2925
2926 let perms_valid = handler
2928 .validate_r6_perms(&perms, &recovered_key, permissions)
2929 .unwrap();
2930 assert!(perms_valid, "Perms must validate with recovered key");
2931
2932 let encrypt_meta = handler
2934 .extract_r6_encrypt_metadata(&perms, &recovered_key)
2935 .unwrap();
2936 assert_eq!(encrypt_meta, Some(true), "EncryptMetadata must be true");
2937 }
2938}