1use crate as pdf;
4use aes::cipher::generic_array::{sequence::Split, GenericArray};
5use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
6use aes::cipher::block_padding::{NoPadding, Pkcs7};
7use sha2::{Digest, Sha256, Sha384, Sha512};
8use std::fmt;
9use std::collections::HashMap;
10use datasize::DataSize;
11use crate::object::PlainRef;
12use crate::primitive::{Dictionary, PdfString, Name};
13use crate::error::{PdfError, Result};
14
15type Aes128CbcEnc = cbc::Encryptor<aes::Aes128>;
16type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
17type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
18
19const PADDING: [u8; 32] = [
20 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41,
21 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
22 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80,
23 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
24];
25
26#[derive(Copy)]
27pub struct Rc4 {
28 i: u8,
29 j: u8,
30 state: [u8; 256]
31}
32
33impl Clone for Rc4 { fn clone(&self) -> Rc4 { *self } }
34
35impl Rc4 {
36 pub fn new(key: &[u8]) -> Rc4 {
37 assert!(!key.is_empty() && key.len() <= 256);
38 let mut rc4 = Rc4 { i: 0, j: 0, state: [0; 256] };
39 for (i, x) in rc4.state.iter_mut().enumerate() {
40 *x = i as u8;
41 }
42 let mut j: u8 = 0;
43 for i in 0..256 {
44 j = j.wrapping_add(rc4.state[i]).wrapping_add(key[i % key.len()]);
45 rc4.state.swap(i, j as usize);
46 }
47 rc4
48 }
49 fn next(&mut self) -> u8 {
50 self.i = self.i.wrapping_add(1);
51 self.j = self.j.wrapping_add(self.state[self.i as usize]);
52 self.state.swap(self.i as usize, self.j as usize);
53 self.state[(self.state[self.i as usize].wrapping_add(self.state[self.j as usize])) as usize]
54 }
55 pub fn encrypt(key: &[u8], data: &mut [u8]) {
56 let mut rc4 = Rc4::new(key);
57 for b in data.iter_mut() {
58 *b ^= rc4.next();
59 }
60 }
61}
62
63#[derive(Object, Debug, Clone, DataSize)]
65pub struct CryptDict {
66 #[pdf(key="O")]
67 o: PdfString,
68
69 #[pdf(key="U")]
70 u: PdfString,
71
72 #[pdf(key="R")]
73 r: u32,
74
75 #[pdf(key="P")]
76 p: i32,
77
78 #[pdf(key="V")]
79 v: i32,
80
81 #[pdf(key="Length", default="40")]
82 bits: u32,
83
84 #[pdf(key="CF")]
85 crypt_filters: HashMap<Name, CryptFilter>,
86
87 #[pdf(key="StmF")]
88 default_crypt_filter: Option<Name>,
89
90 #[pdf(key="EncryptMetadata", default="true")]
91 encrypt_metadata: bool,
92
93 #[pdf(key = "OE")]
94 oe: Option<PdfString>,
95
96 #[pdf(key = "UE")]
97 ue: Option<PdfString>,
98
99 #[pdf(other)]
100 _other: Dictionary
101}
102
103#[derive(Object, Debug, Clone, Copy, DataSize)]
104pub enum CryptMethod {
105 None,
106 V2,
107 AESV2,
108 AESV3,
109}
110
111#[derive(Object, Debug, Clone, Copy, DataSize)]
112pub enum AuthEvent {
113 DocOpen,
114 EFOpen
115}
116
117#[derive(Object, Debug, Clone, DataSize)]
118#[pdf(Type="CryptFilter?")]
119pub struct CryptFilter {
120 #[pdf(key="CFM", default="CryptMethod::None")]
121 pub method: CryptMethod,
122
123 #[pdf(key="AuthEvent", default="AuthEvent::DocOpen")]
124 pub auth_event: AuthEvent,
125
126 #[pdf(key="Length")]
127 pub length: Option<u32>,
128
129 #[pdf(other)]
130 _other: Dictionary
131}
132
133pub struct Decoder {
134 key_size: usize,
135 key: Vec<u8>, method: CryptMethod,
137 pub(crate) encrypt_indirect_object: Option<PlainRef>,
141 pub(crate) metadata_indirect_object: Option<PlainRef>,
146 encrypt_metadata: bool,
149}
150impl Decoder {
151 pub fn default(dict: &CryptDict, id: &[u8]) -> Result<Decoder> {
152 Decoder::from_password(dict, id, b"")
153 }
154
155 fn key(&self) -> &[u8] {
156 &self.key[.. std::cmp::min(self.key_size, 16)]
157 }
158
159 pub fn new(key: Vec<u8>, key_size: usize, method: CryptMethod, encrypt_metadata: bool) -> Decoder {
160 Decoder {
161 key_size,
162 key,
163 method,
164 encrypt_indirect_object: None,
165 metadata_indirect_object: None,
166 encrypt_metadata,
167 }
168 }
169
170 pub fn from_password(dict: &CryptDict, id: &[u8], pass: &[u8]) -> Result<Decoder> {
171 fn compute_u_rev_2(key: &[u8]) -> Vec<u8> {
172 let mut data = PADDING.to_vec();
174 Rc4::encrypt(key, &mut data);
175 data
176 }
177
178 fn check_password_rev_2(document_u: &[u8], key: &[u8]) -> bool {
179 compute_u_rev_2(key) == document_u
180 }
181
182 fn compute_u_rev_3_4(id: &[u8], key: &[u8]) -> [u8; 16] {
183 let mut hash = md5::Context::new();
188 hash.consume(PADDING);
189
190 hash.consume(id);
192
193 let mut data = *hash.compute();
195 Rc4::encrypt(key, &mut data);
196
197 for i in 1u8..=19 {
199 let mut key = key.to_owned();
200 for b in &mut key {
201 *b ^= i;
202 }
203 Rc4::encrypt(&key, &mut data);
204 }
205
206 data
208 }
209
210 fn check_password_rev_3_4(document_u: &[u8], id: &[u8], key: &[u8]) -> bool {
211 document_u.starts_with(&compute_u_rev_3_4(id, key))
212 }
213
214 fn check_password_rc4(revision: u32, document_u: &[u8], id: &[u8], key: &[u8]) -> bool {
215 if revision == 2 {
216 check_password_rev_2(document_u, key)
217 } else {
218 check_password_rev_3_4(document_u, id, key)
219 }
220 }
221
222 fn key_derivation_user_password_rc4(
223 revision: u32,
224 key_size: usize,
225 dict: &CryptDict,
226 id: &[u8],
227 pass: &[u8],
228 ) -> Vec<u8> {
229 let o = dict.o.as_bytes();
230 let p = dict.p;
231 let mut hash = md5::Context::new();
234 if pass.len() < 32 {
235 hash.consume(pass);
236 hash.consume(&PADDING[..32 - pass.len()]);
237 } else {
238 hash.consume(&pass[..32]);
239 }
240
241 hash.consume(o);
243
244 hash.consume(p.to_le_bytes());
246
247 hash.consume(id);
249
250 if revision >= 4 && !dict.encrypt_metadata {
252 hash.consume([0xff, 0xff, 0xff, 0xff]);
253 }
254
255 let mut data = *hash.compute();
257
258 if revision >= 3 {
260 for _ in 0..50 {
261 data = *md5::compute(&data[..std::cmp::min(key_size, 16)]);
262 }
263 }
264
265 let mut key = vec![0u8; key_size.max(16)];
266 key[..16].copy_from_slice(&data);
267 key
268 }
269
270 fn key_derivation_owner_password_rc4(
271 revision: u32,
272 key_size: usize,
273 pass: &[u8],
274 ) -> Result<Vec<u8>> {
275 if key_size > 16 {
276 bail!("key size > 16");
277 }
278
279 let mut hash = md5::Context::new();
280 if pass.len() < 32 {
281 hash.consume(pass);
282 hash.consume(&PADDING[..32 - pass.len()]);
283 } else {
284 hash.consume(&pass[..32]);
285 }
286
287 if revision >= 3 {
288 for _ in 0..50 {
289 let digest = *std::mem::replace(&mut hash, md5::Context::new()).compute();
290 hash.consume(digest);
291 }
292 }
293
294 let digest = &hash.compute()[..key_size];
295 Ok(digest.to_vec())
296 }
297
298 let (key_bits, method) = match dict.v {
299 1 => (40, CryptMethod::V2),
300 2 => {
301 if dict.bits % 8 != 0 {
302 err!(other!("invalid key length {}", dict.bits))
303 } else {
304 (dict.bits, CryptMethod::V2)
305 }
306 },
307 4 ..= 6 => {
308 let default = dict
309 .crypt_filters
310 .get(try_opt!(dict.default_crypt_filter.as_ref()).as_str())
311 .ok_or_else(|| other!("missing crypt filter entry {:?}", dict.default_crypt_filter.as_ref()))?;
312
313 match default.method {
314 CryptMethod::V2 | CryptMethod::AESV2 => (
315 default.length.map(|n| 8 * n).unwrap_or(dict.bits),
316 default.method,
317 ),
318 CryptMethod::AESV3 if dict.v == 5 => (
319 default.length.map(|n| 8 * n).unwrap_or(dict.bits),
320 default.method,
321 ),
322 m => err!(other!("unimplemented crypt method {:?}", m)),
323 }
324 }
325 v => err!(other!("unsupported V value {}", v)),
326 };
327 let level = dict.r;
328 if !(2..=6).contains(&level) {
329 err!(other!("unsupported standard security handler revision {}", level))
330 };
331 if level <= 4 {
332 let key_size = key_bits as usize / 8;
333 let key = key_derivation_user_password_rc4(level, key_size, dict, id, pass);
334
335 if check_password_rc4(level, dict.u.as_bytes(), id, &key[..std::cmp::min(key_size, 16)]) {
336 let decoder = Decoder::new(key, key_size, method, dict.encrypt_metadata);
337 Ok(decoder)
338 } else {
339 let password_wrap_key = key_derivation_owner_password_rc4(level, key_size, pass)?;
340 let mut data = dict.o.as_bytes().to_vec();
341 let rounds = if level == 2 { 1u8 } else { 20u8 };
342 for round in 0..rounds {
343 let mut round_key = password_wrap_key.clone();
344 for byte in round_key.iter_mut() {
345 *byte ^= round;
346 }
347 Rc4::encrypt(&round_key, &mut data);
348 }
349 let unwrapped_user_password = data;
350
351 let key = key_derivation_user_password_rc4(
352 level,
353 key_size,
354 dict,
355 id,
356 &unwrapped_user_password,
357 );
358
359 if check_password_rc4(level, dict.u.as_bytes(), id, &key[..key_size]) {
360 let decoder = Decoder::new(key, key_size, method, dict.encrypt_metadata);
361 Ok(decoder)
362 } else {
363 Err(PdfError::InvalidPassword)
364 }
365 }
366 } else if level == 5 || level == 6 {
367 let u = dict.u.as_bytes();
368 if u.len() != 48 {
369 err!(format!(
370 "U in Encrypt dictionary should have a length of 48 bytes, not {}",
371 u.len(),
372 )
373 .into());
374 }
375 let user_hash = &u[0..32];
376 let user_validation_salt = &u[32..40];
377 let user_key_salt = &u[40..48];
378
379 let o = dict.o.as_bytes();
380 if o.len() != 48 {
381 err!(format!(
382 "O in Encrypt dictionary should have a length of 48 bytes, not {}",
383 o.len(),
384 )
385 .into());
386 }
387 let owner_hash = &o[0..32];
388 let owner_validation_salt = &o[32..40];
389 let owner_key_salt = &o[40..48];
390
391 let password_unicode =
392 t!(String::from_utf8(pass.to_vec()).map_err(|_| PdfError::InvalidPassword));
393 let password_prepped =
394 t!(stringprep::saslprep(&password_unicode).map_err(|_| PdfError::InvalidPassword));
395 let mut password_encoded = password_prepped.as_bytes();
396
397 if password_encoded.len() > 127 {
398 password_encoded = &password_encoded[..127];
399 }
400
401 let ue = t!(dict.ue.as_ref().ok_or_else(|| PdfError::MissingEntry {
402 typ: "Encrypt",
403 field: "UE".into(),
404 }))
405 .as_bytes()
406 .to_vec();
407 let oe = t!(dict.oe.as_ref().ok_or_else(|| PdfError::MissingEntry {
408 typ: "Encrypt",
409 field: "OE".into(),
410 }))
411 .as_bytes()
412 .to_vec();
413
414 let (intermediate_key, mut wrapped_key) = if level == 6 {
415 let user_hash_computed =
416 Self::revision_6_kdf(password_encoded, user_validation_salt, b"");
417 if user_hash_computed == user_hash {
418 (
419 Self::revision_6_kdf(password_encoded, user_key_salt, b"").into(),
420 ue,
421 )
422 } else {
423 let owner_hash_computed =
424 Self::revision_6_kdf(password_encoded, owner_validation_salt, u);
425 if owner_hash_computed == owner_hash {
426 (
427 Self::revision_6_kdf(password_encoded, owner_key_salt, u).into(),
428 oe,
429 )
430 } else {
431 err!(PdfError::InvalidPassword);
432 }
433 }
434 } else {
435 let mut user_check_hash = Sha256::new();
438 user_check_hash.update(password_encoded);
439 user_check_hash.update(user_validation_salt);
440 let user_hash_computed = user_check_hash.finalize();
441 #[allow(clippy::branches_sharing_code)]
442 if user_hash_computed.as_slice() == user_hash {
443 let mut intermediate_kdf_hash = Sha256::new();
444 intermediate_kdf_hash.update(password_encoded);
445 intermediate_kdf_hash.update(user_key_salt);
446 (intermediate_kdf_hash.finalize(), ue)
447 } else {
448 let mut owner_check_hash = Sha256::new();
449 owner_check_hash.update(password_encoded);
450 owner_check_hash.update(owner_validation_salt);
451 owner_check_hash.update(u);
452 let owner_hash_computed = owner_check_hash.finalize();
453 if owner_hash_computed.as_slice() == owner_hash {
454 let mut intermediate_kdf_hash = Sha256::new();
455 intermediate_kdf_hash.update(password_encoded);
456 intermediate_kdf_hash.update(owner_key_salt);
457 intermediate_kdf_hash.update(u);
458 (intermediate_kdf_hash.finalize(), oe)
459 } else {
460 err!(PdfError::InvalidPassword);
461 }
462 }
463 };
464
465 let zero_iv = GenericArray::from_slice(&[0u8; 16]);
466 let key_slice = t!(Aes256CbcDec::new(&intermediate_key, zero_iv)
467 .decrypt_padded_mut::<NoPadding>(&mut wrapped_key)
468 .map_err(|_| PdfError::InvalidPassword));
469
470 let decoder = Decoder::new(key_slice.into(), 32, method, dict.encrypt_metadata);
471 Ok(decoder)
472 } else {
473 err!(format!("unsupported V value {}", level).into())
474 }
475 }
476
477 fn revision_6_kdf(password: &[u8], salt: &[u8], u: &[u8]) -> [u8; 32] {
478 let mut data = [0u8; (128 + 64 + 48) * 64];
479 let mut data_total_len = 0;
480
481 let mut sha256 = Sha256::new();
482 let mut sha384 = Sha384::new();
483 let mut sha512 = Sha512::new();
484
485 let mut input_sha256 = Sha256::new();
486 input_sha256.update(password);
487 input_sha256.update(salt);
488 input_sha256.update(u);
489 let input = input_sha256.finalize();
490 let (mut key, mut iv) = input.split();
491
492 let mut block = [0u8; 64];
493 let mut block_size = 32;
494 (block[..block_size]).copy_from_slice(&input[..block_size]);
495
496 let mut i = 0;
497 while i < 64 || i < data[data_total_len - 1] as usize + 32 {
498 let aes = Aes128CbcEnc::new(&key, &iv);
499 let data_repeat_len = password.len() + block_size + u.len();
500 data[..password.len()].copy_from_slice(password);
501 data[password.len()..password.len() + block_size].copy_from_slice(&block[..block_size]);
502 data[password.len() + block_size..data_repeat_len].copy_from_slice(u);
503 for j in 1..64 {
504 data.copy_within(..data_repeat_len, j * data_repeat_len);
505 }
506 data_total_len = data_repeat_len * 64;
507
508 let encrypted = aes
510 .encrypt_padded_mut::<NoPadding>(&mut data[..data_total_len], data_total_len)
511 .unwrap();
512
513 let sum: usize = encrypted[..16].iter().map(|byte| *byte as usize).sum();
514 block_size = sum % 3 * 16 + 32;
515 match block_size {
516 32 => {
517 sha256.update(encrypted);
518 (block[..block_size]).copy_from_slice(&sha256.finalize_reset());
519 }
520 48 => {
521 sha384.update(encrypted);
522 (block[..block_size]).copy_from_slice(&sha384.finalize_reset());
523 }
524 64 => {
525 sha512.update(encrypted);
526 (block[..block_size]).copy_from_slice(&sha512.finalize_reset());
527 }
528 _ => unreachable!(),
529 }
530
531 key.copy_from_slice(&block[..16]);
532 iv.copy_from_slice(&block[16..32]);
533
534 i += 1;
535 }
536 let mut hash = [0u8; 32];
537 hash.copy_from_slice(&block[..32]);
538 hash
539 }
540
541 pub fn decrypt<'buf>(&self, id: PlainRef, data: &'buf mut [u8]) -> Result<&'buf [u8]> {
542 if self.encrypt_indirect_object == Some(id) {
543 return Ok(data);
545 }
546
547 if !self.encrypt_metadata && self.metadata_indirect_object == Some(id) {
548 return Ok(data);
551 }
552
553 if data.is_empty() {
554 return Ok(data);
555 }
556
557 match self.method {
561 CryptMethod::None => unreachable!(),
562 CryptMethod::V2 => {
563 let mut key = [0; 16 + 5];
565 let n = self.key().len();
566 key[..n].copy_from_slice(self.key());
567 key[n..n + 3].copy_from_slice(&id.id.to_le_bytes()[..3]);
568 key[n + 3..n + 5].copy_from_slice(&id.gen.to_le_bytes()[..2]);
569
570 let key = *md5::compute(&key[..n + 5]);
572
573 Rc4::encrypt(&key[..(n + 5).min(16)], data);
575 Ok(data)
576 }
577 CryptMethod::AESV2 => {
578 let mut key = [0; 32 + 5 + 4];
580 let n = std::cmp::min(self.key_size, 16);
581 key[..n].copy_from_slice(self.key());
582 key[n..n + 3].copy_from_slice(&id.id.to_le_bytes()[..3]);
583 key[n + 3..n + 5].copy_from_slice(&id.gen.to_le_bytes()[..2]);
584 key[n + 5..n + 9].copy_from_slice(b"sAlT");
585
586 let key = *md5::compute(&key[..n + 9]);
588
589 let key = &key[..(n + 5).min(16)];
591 if data.len() < 16 {
592 return Err(PdfError::DecryptionFailure);
593 }
594 let (iv, ciphertext) = data.split_at_mut(16);
595 let cipher =
596 t!(Aes128CbcDec::new_from_slices(key, iv).map_err(|_| PdfError::DecryptionFailure));
597 Ok(t!(cipher
598 .decrypt_padded_mut::<Pkcs7>(ciphertext)
599 .map_err(|_| PdfError::DecryptionFailure)))
600 }
601 CryptMethod::AESV3 => {
602 if data.len() < 16 {
603 return Err(PdfError::DecryptionFailure);
604 }
605 let (iv, ciphertext) = data.split_at_mut(16);
606 let cipher =
607 t!(Aes256CbcDec::new_from_slices(self.key(), iv).map_err(|_| PdfError::DecryptionFailure));
608 Ok(t!(cipher
609 .decrypt_padded_mut::<Pkcs7>(ciphertext)
610 .map_err(|_| PdfError::DecryptionFailure)))
611 }
612 }
613 }
614}
615impl fmt::Debug for Decoder {
616 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
617 f.debug_struct("Decoder")
618 .field("key", &self.key())
619 .field("method", &self.method)
620 .finish()
621 }
622}
623
624#[cfg(test)]
625mod tests {
626 #[test]
627 fn unencrypted_strings() {
628 let data_prefix = b"%PDF-1.5\n\
629 1 0 obj\n\
630 << /Type /Catalog /Pages 2 0 R >>\n\
631 endobj\n\
632 2 0 obj\n\
633 << /Type /Pages /Kids [3 0 R] /Count 1 >>\n\
634 endobj\n\
635 3 0 obj\n\
636 << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>\n\
637 endobj\n\
638 4 0 obj\n\
639 << /Length 0 >>\n\
640 stream\n\
641 endstream\n\
642 endobj\n\
643 5 0 obj\n\
644 <<\n\
645 /V 4\n\
646 /CF <<\n\
647 /StdCF << /Type /CryptFilter /CFM /V2 >>\n\
648 >>\n\
649 /StmF /StdCF\n\
650 /StrF /StdCF\n\
651 /R 4\n\
652 /O (owner pwd hash!!)\n\
653 /U <E721D9D63EC4E7BD4DA6C9F0E30C8290>\n\
654 /P -4\n\
655 >>\n\
656 endobj\n\
657 xref\n\
658 1 5\n";
659 let mut data = data_prefix.to_vec();
660 for obj_nr in 1..=5 {
661 let needle = format!("\n{} 0 obj\n", obj_nr).into_bytes();
662 let offset = data_prefix
663 .windows(needle.len())
664 .position(|w| w == needle)
665 .unwrap()
666 + 1;
667 let mut line = format!("{:010} {:05} n\r\n", offset, 0).into_bytes();
668 assert_eq!(line.len(), 20);
669 data.append(&mut line);
670 }
671 let trailer_snippet = b"trailer\n\
672 <<\n\
673 /Size 6\n\
674 /Root 1 0 R\n\
675 /Encrypt 5 0 R\n\
676 /ID [<DEADBEEF> <DEADBEEF>]\n\
677 >>\n\
678 startxref\n";
679 data.extend_from_slice(trailer_snippet);
680 let xref_offset = data_prefix
681 .windows("xref".len())
682 .rposition(|w| w == b"xref")
683 .unwrap();
684 data.append(&mut format!("{}\n%%EOF", xref_offset).into_bytes());
685
686 let file = crate::file::FileOptions::uncached().load(data).unwrap();
687
688 assert_eq!(
691 file.trailer.encrypt_dict.unwrap().o.as_ref(),
692 b"owner pwd hash!!",
693 );
694 }
695}