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}
31
32impl DocumentEncryption {
33 pub fn new(
35 user_password: impl Into<String>,
36 owner_password: impl Into<String>,
37 permissions: Permissions,
38 strength: EncryptionStrength,
39 ) -> Self {
40 Self {
41 user_password: UserPassword(user_password.into()),
42 owner_password: OwnerPassword(owner_password.into()),
43 permissions,
44 strength,
45 }
46 }
47
48 pub fn with_passwords(
50 user_password: impl Into<String>,
51 owner_password: impl Into<String>,
52 ) -> Self {
53 Self::new(
54 user_password,
55 owner_password,
56 Permissions::all(),
57 EncryptionStrength::Rc4_128bit,
58 )
59 }
60
61 pub fn handler(&self) -> StandardSecurityHandler {
63 match self.strength {
64 EncryptionStrength::Rc4_40bit => StandardSecurityHandler::rc4_40bit(),
65 EncryptionStrength::Rc4_128bit => StandardSecurityHandler::rc4_128bit(),
66 }
67 }
68
69 pub fn create_encryption_dict(&self, file_id: Option<&[u8]>) -> Result<EncryptionDictionary> {
71 let handler = self.handler();
72
73 let owner_hash = handler.compute_owner_hash(&self.owner_password, &self.user_password);
75 let user_hash = handler.compute_user_hash(
76 &self.user_password,
77 &owner_hash,
78 self.permissions,
79 file_id,
80 )?;
81
82 let enc_dict = match self.strength {
84 EncryptionStrength::Rc4_40bit => EncryptionDictionary::rc4_40bit(
85 owner_hash,
86 user_hash,
87 self.permissions,
88 file_id.map(|id| id.to_vec()),
89 ),
90 EncryptionStrength::Rc4_128bit => EncryptionDictionary::rc4_128bit(
91 owner_hash,
92 user_hash,
93 self.permissions,
94 file_id.map(|id| id.to_vec()),
95 ),
96 };
97
98 Ok(enc_dict)
99 }
100
101 pub fn get_encryption_key(
103 &self,
104 enc_dict: &EncryptionDictionary,
105 file_id: Option<&[u8]>,
106 ) -> Result<EncryptionKey> {
107 let handler = self.handler();
108 handler.compute_encryption_key(&self.user_password, &enc_dict.o, self.permissions, file_id)
109 }
110}
111
112#[allow(dead_code)]
114pub struct EncryptionContext {
115 handler: StandardSecurityHandler,
117 key: EncryptionKey,
119}
120
121#[allow(dead_code)]
122impl EncryptionContext {
123 pub fn new(handler: StandardSecurityHandler, key: EncryptionKey) -> Self {
125 Self { handler, key }
126 }
127
128 pub fn encrypt_string(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
130 self.handler.encrypt_string(data, &self.key, obj_id)
131 }
132
133 pub fn decrypt_string(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
135 self.handler.decrypt_string(data, &self.key, obj_id)
136 }
137
138 pub fn encrypt_stream(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
140 self.handler.encrypt_stream(data, &self.key, obj_id)
141 }
142
143 pub fn decrypt_stream(&self, data: &[u8], obj_id: &ObjectId) -> Vec<u8> {
145 self.handler.decrypt_stream(data, &self.key, obj_id)
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn test_document_encryption_new() {
155 let enc = DocumentEncryption::new(
156 "user123",
157 "owner456",
158 Permissions::all(),
159 EncryptionStrength::Rc4_128bit,
160 );
161
162 assert_eq!(enc.user_password.0, "user123");
163 assert_eq!(enc.owner_password.0, "owner456");
164 }
165
166 #[test]
167 fn test_with_passwords() {
168 let enc = DocumentEncryption::with_passwords("user", "owner");
169 assert_eq!(enc.user_password.0, "user");
170 assert_eq!(enc.owner_password.0, "owner");
171 assert!(enc.permissions.can_print());
172 assert!(enc.permissions.can_modify_contents());
173 }
174
175 #[test]
176 fn test_encryption_dict_creation() {
177 let enc = DocumentEncryption::new(
178 "test",
179 "owner",
180 Permissions::new(),
181 EncryptionStrength::Rc4_40bit,
182 );
183
184 let enc_dict = enc.create_encryption_dict(None).unwrap();
185 assert_eq!(enc_dict.v, 1);
186 assert_eq!(enc_dict.r, 2);
187 assert_eq!(enc_dict.length, Some(5));
188 }
189
190 #[test]
191 fn test_encryption_context() {
192 let handler = StandardSecurityHandler::rc4_40bit();
193 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5]);
194 let ctx = EncryptionContext::new(handler, key);
195
196 let obj_id = ObjectId::new(1, 0);
197 let plaintext = b"Hello, World!";
198
199 let encrypted = ctx.encrypt_string(plaintext, &obj_id);
200 assert_ne!(encrypted, plaintext);
201
202 let decrypted = ctx.decrypt_string(&encrypted, &obj_id);
203 assert_eq!(decrypted, plaintext);
204 }
205
206 #[test]
207 fn test_encryption_strength_variants() {
208 let enc_40 = DocumentEncryption::new(
209 "user",
210 "owner",
211 Permissions::new(),
212 EncryptionStrength::Rc4_40bit,
213 );
214
215 let enc_128 = DocumentEncryption::new(
216 "user",
217 "owner",
218 Permissions::new(),
219 EncryptionStrength::Rc4_128bit,
220 );
221
222 let _handler_40 = enc_40.handler();
224 let _handler_128 = enc_128.handler();
225
226 let dict_40 = enc_40.create_encryption_dict(None).unwrap();
228 let dict_128 = enc_128.create_encryption_dict(None).unwrap();
229
230 assert_eq!(dict_40.v, 1);
231 assert_eq!(dict_40.r, 2);
232 assert_eq!(dict_40.length, Some(5));
233
234 assert_eq!(dict_128.v, 2);
235 assert_eq!(dict_128.r, 3);
236 assert_eq!(dict_128.length, Some(16));
237 }
238
239 #[test]
240 fn test_empty_passwords() {
241 let enc =
242 DocumentEncryption::new("", "", Permissions::all(), EncryptionStrength::Rc4_128bit);
243
244 assert_eq!(enc.user_password.0, "");
245 assert_eq!(enc.owner_password.0, "");
246
247 let dict = enc.create_encryption_dict(None);
249 assert!(dict.is_ok());
250 }
251
252 #[test]
253 fn test_long_passwords() {
254 let long_user = "a".repeat(100);
255 let long_owner = "b".repeat(100);
256
257 let enc = DocumentEncryption::new(
258 &long_user,
259 &long_owner,
260 Permissions::new(),
261 EncryptionStrength::Rc4_128bit,
262 );
263
264 assert_eq!(enc.user_password.0.len(), 100);
265 assert_eq!(enc.owner_password.0.len(), 100);
266
267 let dict = enc.create_encryption_dict(None);
268 assert!(dict.is_ok());
269 }
270
271 #[test]
272 fn test_unicode_passwords() {
273 let enc = DocumentEncryption::new(
274 "contraseña",
275 "密码",
276 Permissions::all(),
277 EncryptionStrength::Rc4_40bit,
278 );
279
280 assert_eq!(enc.user_password.0, "contraseña");
281 assert_eq!(enc.owner_password.0, "密码");
282
283 let dict = enc.create_encryption_dict(None);
284 assert!(dict.is_ok());
285 }
286
287 #[test]
288 fn test_encryption_with_file_id() {
289 let enc = DocumentEncryption::new(
290 "user",
291 "owner",
292 Permissions::new(),
293 EncryptionStrength::Rc4_128bit,
294 );
295
296 let file_id = b"test_file_id_12345";
297 let dict = enc.create_encryption_dict(Some(file_id)).unwrap();
298
299 let key = enc.get_encryption_key(&dict, Some(file_id));
301 assert!(key.is_ok());
302 }
303
304 #[test]
305 fn test_different_permissions() {
306 let perms_none = Permissions::new();
307 let perms_all = Permissions::all();
308 let mut perms_custom = Permissions::new();
309 perms_custom.set_print(true);
310 perms_custom.set_modify_contents(false);
311
312 let enc1 =
313 DocumentEncryption::new("user", "owner", perms_none, EncryptionStrength::Rc4_128bit);
314
315 let enc2 =
316 DocumentEncryption::new("user", "owner", perms_all, EncryptionStrength::Rc4_128bit);
317
318 let enc3 = DocumentEncryption::new(
319 "user",
320 "owner",
321 perms_custom,
322 EncryptionStrength::Rc4_128bit,
323 );
324
325 let _dict1 = enc1.create_encryption_dict(None).unwrap();
327 let _dict2 = enc2.create_encryption_dict(None).unwrap();
328 let _dict3 = enc3.create_encryption_dict(None).unwrap();
329
330 }
334
335 #[test]
336 fn test_encryption_context_stream() {
337 let handler = StandardSecurityHandler::rc4_128bit();
338 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
339 let ctx = EncryptionContext::new(handler, key);
340
341 let obj_id = ObjectId::new(5, 0);
342 let stream_data = b"This is a PDF stream content that needs encryption";
343
344 let encrypted = ctx.encrypt_stream(stream_data, &obj_id);
345 assert_ne!(encrypted, stream_data);
346
347 let decrypted = ctx.decrypt_stream(&encrypted, &obj_id);
348 assert_eq!(decrypted, stream_data);
349 }
350
351 #[test]
352 fn test_encryption_context_different_objects() {
353 let handler = StandardSecurityHandler::rc4_40bit();
354 let key = EncryptionKey::new(vec![1, 2, 3, 4, 5]);
355 let ctx = EncryptionContext::new(handler, key);
356
357 let obj_id1 = ObjectId::new(1, 0);
358 let obj_id2 = ObjectId::new(2, 0);
359 let plaintext = b"Test data";
360
361 let encrypted1 = ctx.encrypt_string(plaintext, &obj_id1);
362 let encrypted2 = ctx.encrypt_string(plaintext, &obj_id2);
363
364 assert_ne!(encrypted1, encrypted2);
366
367 assert_eq!(ctx.decrypt_string(&encrypted1, &obj_id1), plaintext);
369 assert_eq!(ctx.decrypt_string(&encrypted2, &obj_id2), plaintext);
370 }
371
372 #[test]
373 fn test_get_encryption_key_consistency() {
374 let enc = DocumentEncryption::new(
375 "user123",
376 "owner456",
377 Permissions::all(),
378 EncryptionStrength::Rc4_128bit,
379 );
380
381 let file_id = b"consistent_file_id";
382 let dict = enc.create_encryption_dict(Some(file_id)).unwrap();
383
384 let key1 = enc.get_encryption_key(&dict, Some(file_id));
386 let key2 = enc.get_encryption_key(&dict, Some(file_id));
387
388 assert!(key1.is_ok());
390 assert!(key2.is_ok());
391 }
392
393 #[test]
394 fn test_handler_selection() {
395 let enc_40 = DocumentEncryption::new(
396 "test",
397 "test",
398 Permissions::new(),
399 EncryptionStrength::Rc4_40bit,
400 );
401
402 let enc_128 = DocumentEncryption::new(
403 "test",
404 "test",
405 Permissions::new(),
406 EncryptionStrength::Rc4_128bit,
407 );
408
409 let _handler_40 = enc_40.handler();
411 let _handler_128 = enc_128.handler();
412
413 let dict_40 = enc_40.create_encryption_dict(None).unwrap();
415 let dict_128 = enc_128.create_encryption_dict(None).unwrap();
416
417 assert_eq!(dict_40.length, Some(5));
419 assert_eq!(dict_128.length, Some(16));
420 }
421}