1use crate::encryption::{
4 EncryptionDictionary, EncryptionKey, OwnerPassword, Permissions, StandardSecurityHandler,
5 UserPassword,
6};
7use crate::error::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, &self.user_password)?;
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 =
136 handler.compute_r5_oe_entry(&self.owner_password, &o_entry, &encryption_key)?;
137
138 Ok(EncryptionDictionary::aes_256(
139 o_entry,
140 u_entry,
141 self.permissions,
142 file_id.map(|id| id.to_vec()),
143 )
144 .with_r5_entries(ue_entry, oe_entry))
145 }
146
147 pub fn get_encryption_key(
149 &self,
150 enc_dict: &EncryptionDictionary,
151 file_id: Option<&[u8]>,
152 ) -> Result<EncryptionKey> {
153 let handler = self.handler();
154 handler.compute_encryption_key(&self.user_password, &enc_dict.o, self.permissions, file_id)
155 }
156}
157
158#[allow(dead_code)]
160pub struct EncryptionContext {
161 handler: StandardSecurityHandler,
163 key: EncryptionKey,
165}
166
167#[allow(dead_code)]
168impl EncryptionContext {
169 pub fn new(handler: StandardSecurityHandler, key: EncryptionKey) -> Self {
171 Self { handler, key }
172 }
173
174 pub fn encrypt_string(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
176 self.handler.encrypt_string(data, &self.key, obj_id)
177 }
178
179 pub fn decrypt_string(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
181 self.handler.decrypt_string(data, &self.key, obj_id)
182 }
183
184 pub fn encrypt_stream(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
186 self.handler.encrypt_stream(data, &self.key, obj_id)
187 }
188
189 pub fn decrypt_stream(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
191 self.handler.decrypt_stream(data, &self.key, obj_id)
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198
199 #[test]
200 fn test_document_encryption_new() {
201 let enc = DocumentEncryption::new(
202 "user123",
203 "owner456",
204 Permissions::all(),
205 EncryptionStrength::Rc4_128bit,
206 );
207
208 assert_eq!(enc.user_password.0, "user123");
209 assert_eq!(enc.owner_password.0, "owner456");
210 }
211
212 #[test]
213 fn test_with_passwords() {
214 let enc = DocumentEncryption::with_passwords("user", "owner");
215 assert_eq!(enc.user_password.0, "user");
216 assert_eq!(enc.owner_password.0, "owner");
217 assert!(enc.permissions.can_print());
218 assert!(enc.permissions.can_modify_contents());
219 }
220
221 #[test]
222 fn test_encryption_dict_creation() {
223 let enc = DocumentEncryption::new(
224 "test",
225 "owner",
226 Permissions::new(),
227 EncryptionStrength::Rc4_40bit,
228 );
229
230 let enc_dict = enc.create_encryption_dict(None).unwrap();
231 assert_eq!(enc_dict.v, 1);
232 assert_eq!(enc_dict.r, 2);
233 assert_eq!(enc_dict.length, Some(5));
234 }
235
236 #[test]
237 fn test_encryption_context() {
238 let handler = StandardSecurityHandler::rc4_40bit();
239 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5]);
240 let ctx = EncryptionContext::new(handler, key);
241
242 let obj_id = ObjectId::new(1, 0);
243 let plaintext = b"Hello, World!";
244
245 let encrypted = ctx.encrypt_string(plaintext, &obj_id);
246 assert_ne!(encrypted, plaintext);
247
248 let decrypted = ctx.decrypt_string(&encrypted, &obj_id);
249 assert_eq!(decrypted, plaintext);
250 }
251
252 #[test]
253 fn test_encryption_strength_variants() {
254 let enc_40 = DocumentEncryption::new(
255 "user",
256 "owner",
257 Permissions::new(),
258 EncryptionStrength::Rc4_40bit,
259 );
260
261 let enc_128 = DocumentEncryption::new(
262 "user",
263 "owner",
264 Permissions::new(),
265 EncryptionStrength::Rc4_128bit,
266 );
267
268 let _handler_40 = enc_40.handler();
270 let _handler_128 = enc_128.handler();
271
272 let dict_40 = enc_40.create_encryption_dict(None).unwrap();
274 let dict_128 = enc_128.create_encryption_dict(None).unwrap();
275
276 assert_eq!(dict_40.v, 1);
277 assert_eq!(dict_40.r, 2);
278 assert_eq!(dict_40.length, Some(5));
279
280 assert_eq!(dict_128.v, 2);
281 assert_eq!(dict_128.r, 3);
282 assert_eq!(dict_128.length, Some(16));
283 }
284
285 #[test]
286 fn test_empty_passwords() {
287 let enc =
288 DocumentEncryption::new("", "", Permissions::all(), EncryptionStrength::Rc4_128bit);
289
290 assert_eq!(enc.user_password.0, "");
291 assert_eq!(enc.owner_password.0, "");
292
293 let dict = enc.create_encryption_dict(None);
295 assert!(dict.is_ok());
296 }
297
298 #[test]
299 fn test_long_passwords() {
300 let long_user = "a".repeat(100);
301 let long_owner = "b".repeat(100);
302
303 let enc = DocumentEncryption::new(
304 &long_user,
305 &long_owner,
306 Permissions::new(),
307 EncryptionStrength::Rc4_128bit,
308 );
309
310 assert_eq!(enc.user_password.0.len(), 100);
311 assert_eq!(enc.owner_password.0.len(), 100);
312
313 let dict = enc.create_encryption_dict(None);
314 assert!(dict.is_ok());
315 }
316
317 #[test]
318 fn test_unicode_passwords() {
319 let enc = DocumentEncryption::new(
320 "contraseña",
321 "密码",
322 Permissions::all(),
323 EncryptionStrength::Rc4_40bit,
324 );
325
326 assert_eq!(enc.user_password.0, "contraseña");
327 assert_eq!(enc.owner_password.0, "密码");
328
329 let dict = enc.create_encryption_dict(None);
330 assert!(dict.is_ok());
331 }
332
333 #[test]
334 fn test_encryption_with_file_id() {
335 let enc = DocumentEncryption::new(
336 "user",
337 "owner",
338 Permissions::new(),
339 EncryptionStrength::Rc4_128bit,
340 );
341
342 let file_id = b"test_file_id_12345";
343 let dict = enc.create_encryption_dict(Some(file_id)).unwrap();
344
345 let key = enc.get_encryption_key(&dict, Some(file_id));
347 assert!(key.is_ok());
348 }
349
350 #[test]
351 fn test_different_permissions() {
352 let perms_none = Permissions::new();
353 let perms_all = Permissions::all();
354 let mut perms_custom = Permissions::new();
355 perms_custom.set_print(true);
356 perms_custom.set_modify_contents(false);
357
358 let enc1 =
359 DocumentEncryption::new("user", "owner", perms_none, EncryptionStrength::Rc4_128bit);
360
361 let enc2 =
362 DocumentEncryption::new("user", "owner", perms_all, EncryptionStrength::Rc4_128bit);
363
364 let enc3 = DocumentEncryption::new(
365 "user",
366 "owner",
367 perms_custom,
368 EncryptionStrength::Rc4_128bit,
369 );
370
371 let _dict1 = enc1.create_encryption_dict(None).unwrap();
373 let _dict2 = enc2.create_encryption_dict(None).unwrap();
374 let _dict3 = enc3.create_encryption_dict(None).unwrap();
375
376 }
380
381 #[test]
382 fn test_encryption_context_stream() {
383 let handler = StandardSecurityHandler::rc4_128bit();
384 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
385 let ctx = EncryptionContext::new(handler, key);
386
387 let obj_id = ObjectId::new(5, 0);
388 let stream_data = b"This is a PDF stream content that needs encryption";
389
390 let encrypted = ctx.encrypt_stream(stream_data, &obj_id);
391 assert_ne!(encrypted, stream_data);
392
393 let decrypted = ctx.decrypt_stream(&encrypted, &obj_id);
394 assert_eq!(decrypted, stream_data);
395 }
396
397 #[test]
398 fn test_encryption_context_different_objects() {
399 let handler = StandardSecurityHandler::rc4_40bit();
400 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5]);
401 let ctx = EncryptionContext::new(handler, key);
402
403 let obj_id1 = ObjectId::new(1, 0);
404 let obj_id2 = ObjectId::new(2, 0);
405 let plaintext = b"Test data";
406
407 let encrypted1 = ctx.encrypt_string(plaintext, &obj_id1);
408 let encrypted2 = ctx.encrypt_string(plaintext, &obj_id2);
409
410 assert_ne!(encrypted1, encrypted2);
412
413 assert_eq!(ctx.decrypt_string(&encrypted1, &obj_id1), plaintext);
415 assert_eq!(ctx.decrypt_string(&encrypted2, &obj_id2), plaintext);
416 }
417
418 #[test]
419 fn test_get_encryption_key_consistency() {
420 let enc = DocumentEncryption::new(
421 "user123",
422 "owner456",
423 Permissions::all(),
424 EncryptionStrength::Rc4_128bit,
425 );
426
427 let file_id = b"consistent_file_id";
428 let dict = enc.create_encryption_dict(Some(file_id)).unwrap();
429
430 let key1 = enc.get_encryption_key(&dict, Some(file_id));
432 let key2 = enc.get_encryption_key(&dict, Some(file_id));
433
434 assert!(key1.is_ok());
436 assert!(key2.is_ok());
437 }
438
439 #[test]
440 fn test_handler_selection() {
441 let enc_40 = DocumentEncryption::new(
442 "test",
443 "test",
444 Permissions::new(),
445 EncryptionStrength::Rc4_40bit,
446 );
447
448 let enc_128 = DocumentEncryption::new(
449 "test",
450 "test",
451 Permissions::new(),
452 EncryptionStrength::Rc4_128bit,
453 );
454
455 let _handler_40 = enc_40.handler();
457 let _handler_128 = enc_128.handler();
458
459 let dict_40 = enc_40.create_encryption_dict(None).unwrap();
461 let dict_128 = enc_128.create_encryption_dict(None).unwrap();
462
463 assert_eq!(dict_40.length, Some(5));
465 assert_eq!(dict_128.length, Some(16));
466 }
467}