1use crate::encryption::{
4 EncryptionDictionary, EncryptionKey, OwnerPassword, Permissions, StandardSecurityHandler,
5 UserPassword,
6};
7use crate::error::{PdfError, Result};
8use crate::objects::ObjectId;
9
10#[derive(Debug, Clone)]
12pub struct DocumentEncryption {
13 pub user_password: UserPassword,
15 pub owner_password: OwnerPassword,
17 pub permissions: Permissions,
19 pub strength: EncryptionStrength,
21}
22
23#[derive(Debug, Clone, Copy)]
25pub enum EncryptionStrength {
26 Rc4_40bit,
28 Rc4_128bit,
30 Aes128,
32 Aes256,
34}
35
36impl DocumentEncryption {
37 pub fn new(
39 user_password: impl Into<String>,
40 owner_password: impl Into<String>,
41 permissions: Permissions,
42 strength: EncryptionStrength,
43 ) -> Self {
44 Self {
45 user_password: UserPassword(user_password.into()),
46 owner_password: OwnerPassword(owner_password.into()),
47 permissions,
48 strength,
49 }
50 }
51
52 pub fn with_passwords(
54 user_password: impl Into<String>,
55 owner_password: impl Into<String>,
56 ) -> Self {
57 Self::new(
58 user_password,
59 owner_password,
60 Permissions::all(),
61 EncryptionStrength::Rc4_128bit,
62 )
63 }
64
65 pub fn handler(&self) -> StandardSecurityHandler {
67 match self.strength {
68 EncryptionStrength::Rc4_40bit => StandardSecurityHandler::rc4_40bit(),
69 EncryptionStrength::Rc4_128bit => StandardSecurityHandler::rc4_128bit(),
70 EncryptionStrength::Aes128 => StandardSecurityHandler::aes_128_r4(),
71 EncryptionStrength::Aes256 => StandardSecurityHandler::aes_256_r5(),
72 }
73 }
74
75 pub fn create_encryption_dict(&self, file_id: Option<&[u8]>) -> Result<EncryptionDictionary> {
77 let handler = self.handler();
78
79 if matches!(self.strength, EncryptionStrength::Aes256) {
81 return self.create_aes256_encryption_dict(&handler, file_id);
82 }
83
84 let owner_hash = handler.compute_owner_hash(&self.owner_password, &self.user_password);
86 let user_hash = handler.compute_user_hash(
87 &self.user_password,
88 &owner_hash,
89 self.permissions,
90 file_id,
91 )?;
92
93 let enc_dict = match self.strength {
94 EncryptionStrength::Rc4_40bit => EncryptionDictionary::rc4_40bit(
95 owner_hash,
96 user_hash,
97 self.permissions,
98 file_id.map(|id| id.to_vec()),
99 ),
100 EncryptionStrength::Rc4_128bit => EncryptionDictionary::rc4_128bit(
101 owner_hash,
102 user_hash,
103 self.permissions,
104 file_id.map(|id| id.to_vec()),
105 ),
106 EncryptionStrength::Aes128 => EncryptionDictionary::aes_128(
107 owner_hash,
108 user_hash,
109 self.permissions,
110 file_id.map(|id| id.to_vec()),
111 ),
112 EncryptionStrength::Aes256 => unreachable!("handled above"),
113 };
114
115 Ok(enc_dict)
116 }
117
118 fn create_aes256_encryption_dict(
120 &self,
121 handler: &StandardSecurityHandler,
122 file_id: Option<&[u8]>,
123 ) -> Result<EncryptionDictionary> {
124 let u_entry = handler.compute_r5_user_hash(&self.user_password)?;
125 let o_entry = handler.compute_r5_owner_hash(&self.owner_password, &u_entry)?;
126
127 let mut encryption_key = vec![0u8; 32];
129 use rand::Rng;
130 rand::rng().fill_bytes(&mut encryption_key);
131 let enc_key_obj = EncryptionKey::new(encryption_key.clone());
132
133 let ue_entry = handler.compute_r5_ue_entry(&self.user_password, &u_entry, &enc_key_obj)?;
135 let oe_entry = handler.compute_r5_oe_entry(
136 &self.owner_password,
137 &o_entry,
138 &u_entry,
139 &encryption_key,
140 )?;
141 let perms_entry = handler.compute_perms_entry(self.permissions, &enc_key_obj, true)?;
142
143 EncryptionDictionary::aes_256(
144 o_entry,
145 u_entry,
146 self.permissions,
147 file_id.map(|id| id.to_vec()),
148 )
149 .with_r5_entries(ue_entry, oe_entry)
150 .with_perms(perms_entry)
151 }
152
153 pub fn get_encryption_key(
162 &self,
163 enc_dict: &EncryptionDictionary,
164 file_id: Option<&[u8]>,
165 ) -> Result<EncryptionKey> {
166 let handler = self.handler();
167 if matches!(self.strength, EncryptionStrength::Aes256) {
168 let ue = enc_dict.ue.as_deref().ok_or_else(|| {
169 PdfError::EncryptionError("AES-256 encryption dict missing UE entry".to_string())
170 })?;
171 return handler.recover_r5_encryption_key(&self.user_password, &enc_dict.u, ue);
172 }
173 handler.compute_encryption_key(&self.user_password, &enc_dict.o, self.permissions, file_id)
174 }
175}
176
177#[allow(dead_code)]
179pub struct EncryptionContext {
180 handler: StandardSecurityHandler,
182 key: EncryptionKey,
184}
185
186#[allow(dead_code)]
187impl EncryptionContext {
188 pub fn new(handler: StandardSecurityHandler, key: EncryptionKey) -> Self {
190 Self { handler, key }
191 }
192
193 pub fn encrypt_string(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
195 self.handler.encrypt_string(data, &self.key, obj_id)
196 }
197
198 pub fn decrypt_string(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
200 self.handler.decrypt_string(data, &self.key, obj_id)
201 }
202
203 pub fn encrypt_stream(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
205 self.handler.encrypt_stream(data, &self.key, obj_id)
206 }
207
208 pub fn decrypt_stream(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
210 self.handler.decrypt_stream(data, &self.key, obj_id)
211 }
212}
213
214#[cfg(test)]
215mod tests {
216 use super::*;
217
218 #[test]
219 fn test_document_encryption_new() {
220 let enc = DocumentEncryption::new(
221 "user123",
222 "owner456",
223 Permissions::all(),
224 EncryptionStrength::Rc4_128bit,
225 );
226
227 assert_eq!(enc.user_password.0, "user123");
228 assert_eq!(enc.owner_password.0, "owner456");
229 }
230
231 #[test]
232 fn test_with_passwords() {
233 let enc = DocumentEncryption::with_passwords("user", "owner");
234 assert_eq!(enc.user_password.0, "user");
235 assert_eq!(enc.owner_password.0, "owner");
236 assert!(enc.permissions.can_print());
237 assert!(enc.permissions.can_modify_contents());
238 }
239
240 #[test]
241 fn test_encryption_dict_creation() {
242 let enc = DocumentEncryption::new(
243 "test",
244 "owner",
245 Permissions::new(),
246 EncryptionStrength::Rc4_40bit,
247 );
248
249 let enc_dict = enc.create_encryption_dict(None).unwrap();
250 assert_eq!(enc_dict.v, 1);
251 assert_eq!(enc_dict.r, 2);
252 assert_eq!(enc_dict.length, Some(5));
253 }
254
255 #[test]
256 fn test_encryption_context() {
257 let handler = StandardSecurityHandler::rc4_40bit();
258 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5]);
259 let ctx = EncryptionContext::new(handler, key);
260
261 let obj_id = ObjectId::new(1, 0);
262 let plaintext = b"Hello, World!";
263
264 let encrypted = ctx.encrypt_string(plaintext, &obj_id);
265 assert_ne!(encrypted, plaintext);
266
267 let decrypted = ctx.decrypt_string(&encrypted, &obj_id);
268 assert_eq!(decrypted, plaintext);
269 }
270
271 #[test]
272 fn test_encryption_strength_variants() {
273 let enc_40 = DocumentEncryption::new(
274 "user",
275 "owner",
276 Permissions::new(),
277 EncryptionStrength::Rc4_40bit,
278 );
279
280 let enc_128 = DocumentEncryption::new(
281 "user",
282 "owner",
283 Permissions::new(),
284 EncryptionStrength::Rc4_128bit,
285 );
286
287 let _handler_40 = enc_40.handler();
289 let _handler_128 = enc_128.handler();
290
291 let dict_40 = enc_40.create_encryption_dict(None).unwrap();
293 let dict_128 = enc_128.create_encryption_dict(None).unwrap();
294
295 assert_eq!(dict_40.v, 1);
296 assert_eq!(dict_40.r, 2);
297 assert_eq!(dict_40.length, Some(5));
298
299 assert_eq!(dict_128.v, 2);
300 assert_eq!(dict_128.r, 3);
301 assert_eq!(dict_128.length, Some(16));
302 }
303
304 #[test]
305 fn test_empty_passwords() {
306 let enc =
307 DocumentEncryption::new("", "", Permissions::all(), EncryptionStrength::Rc4_128bit);
308
309 assert_eq!(enc.user_password.0, "");
310 assert_eq!(enc.owner_password.0, "");
311
312 let dict = enc.create_encryption_dict(None);
314 assert!(dict.is_ok());
315 }
316
317 #[test]
318 fn test_long_passwords() {
319 let long_user = "a".repeat(100);
320 let long_owner = "b".repeat(100);
321
322 let enc = DocumentEncryption::new(
323 &long_user,
324 &long_owner,
325 Permissions::new(),
326 EncryptionStrength::Rc4_128bit,
327 );
328
329 assert_eq!(enc.user_password.0.len(), 100);
330 assert_eq!(enc.owner_password.0.len(), 100);
331
332 let dict = enc.create_encryption_dict(None);
333 assert!(dict.is_ok());
334 }
335
336 #[test]
337 fn test_unicode_passwords() {
338 let enc = DocumentEncryption::new(
339 "contraseña",
340 "密码",
341 Permissions::all(),
342 EncryptionStrength::Rc4_40bit,
343 );
344
345 assert_eq!(enc.user_password.0, "contraseña");
346 assert_eq!(enc.owner_password.0, "密码");
347
348 let dict = enc.create_encryption_dict(None);
349 assert!(dict.is_ok());
350 }
351
352 #[test]
353 fn test_encryption_with_file_id() {
354 let enc = DocumentEncryption::new(
355 "user",
356 "owner",
357 Permissions::new(),
358 EncryptionStrength::Rc4_128bit,
359 );
360
361 let file_id = b"test_file_id_12345";
362 let dict = enc.create_encryption_dict(Some(file_id)).unwrap();
363
364 let key = enc.get_encryption_key(&dict, Some(file_id));
366 assert!(key.is_ok());
367 }
368
369 #[test]
370 fn test_different_permissions() {
371 let perms_none = Permissions::new();
372 let perms_all = Permissions::all();
373 let mut perms_custom = Permissions::new();
374 perms_custom.set_print(true);
375 perms_custom.set_modify_contents(false);
376
377 let enc1 =
378 DocumentEncryption::new("user", "owner", perms_none, EncryptionStrength::Rc4_128bit);
379
380 let enc2 =
381 DocumentEncryption::new("user", "owner", perms_all, EncryptionStrength::Rc4_128bit);
382
383 let enc3 = DocumentEncryption::new(
384 "user",
385 "owner",
386 perms_custom,
387 EncryptionStrength::Rc4_128bit,
388 );
389
390 let _dict1 = enc1.create_encryption_dict(None).unwrap();
392 let _dict2 = enc2.create_encryption_dict(None).unwrap();
393 let _dict3 = enc3.create_encryption_dict(None).unwrap();
394
395 }
399
400 #[test]
401 fn test_encryption_context_stream() {
402 let handler = StandardSecurityHandler::rc4_128bit();
403 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
404 let ctx = EncryptionContext::new(handler, key);
405
406 let obj_id = ObjectId::new(5, 0);
407 let stream_data = b"This is a PDF stream content that needs encryption";
408
409 let encrypted = ctx.encrypt_stream(stream_data, &obj_id);
410 assert_ne!(encrypted, stream_data);
411
412 let decrypted = ctx.decrypt_stream(&encrypted, &obj_id);
413 assert_eq!(decrypted, stream_data);
414 }
415
416 #[test]
417 fn test_encryption_context_different_objects() {
418 let handler = StandardSecurityHandler::rc4_40bit();
419 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5]);
420 let ctx = EncryptionContext::new(handler, key);
421
422 let obj_id1 = ObjectId::new(1, 0);
423 let obj_id2 = ObjectId::new(2, 0);
424 let plaintext = b"Test data";
425
426 let encrypted1 = ctx.encrypt_string(plaintext, &obj_id1);
427 let encrypted2 = ctx.encrypt_string(plaintext, &obj_id2);
428
429 assert_ne!(encrypted1, encrypted2);
431
432 assert_eq!(ctx.decrypt_string(&encrypted1, &obj_id1), plaintext);
434 assert_eq!(ctx.decrypt_string(&encrypted2, &obj_id2), plaintext);
435 }
436
437 #[test]
438 fn test_get_encryption_key_consistency() {
439 let enc = DocumentEncryption::new(
440 "user123",
441 "owner456",
442 Permissions::all(),
443 EncryptionStrength::Rc4_128bit,
444 );
445
446 let file_id = b"consistent_file_id";
447 let dict = enc.create_encryption_dict(Some(file_id)).unwrap();
448
449 let key1 = enc.get_encryption_key(&dict, Some(file_id));
451 let key2 = enc.get_encryption_key(&dict, Some(file_id));
452
453 assert!(key1.is_ok());
455 assert!(key2.is_ok());
456 }
457
458 #[test]
459 fn test_handler_selection() {
460 let enc_40 = DocumentEncryption::new(
461 "test",
462 "test",
463 Permissions::new(),
464 EncryptionStrength::Rc4_40bit,
465 );
466
467 let enc_128 = DocumentEncryption::new(
468 "test",
469 "test",
470 Permissions::new(),
471 EncryptionStrength::Rc4_128bit,
472 );
473
474 let _handler_40 = enc_40.handler();
476 let _handler_128 = enc_128.handler();
477
478 let dict_40 = enc_40.create_encryption_dict(None).unwrap();
480 let dict_128 = enc_128.create_encryption_dict(None).unwrap();
481
482 assert_eq!(dict_40.length, Some(5));
484 assert_eq!(dict_128.length, Some(16));
485 }
486}