pdfluent_lopdf/encryption/
crypt_filters.rs1use super::DecryptionError;
2use super::pkcs5::Pkcs5;
3use super::rc4::Rc4;
4use crate::ObjectId;
5use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
6use md5::{Digest as _, Md5};
7use rand::Rng as _;
8
9type Aes128CbcEnc = cbc::Encryptor<aes::Aes128>;
10type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
11
12type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
13type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
14
15pub trait CryptFilter: std::fmt::Debug + Send + Sync {
16 fn method(&self) -> &[u8];
17 fn compute_key(&self, key: &[u8], obj_id: ObjectId) -> Result<Vec<u8>, DecryptionError>;
18 fn encrypt(&self, key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, DecryptionError>;
19 fn decrypt(&self, key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, DecryptionError>;
20}
21
22#[derive(Clone, Copy, Debug)]
23pub struct IdentityCryptFilter;
24
25impl CryptFilter for IdentityCryptFilter {
26 fn method(&self) -> &[u8] {
27 b"Identity"
28 }
29
30 fn compute_key(&self, key: &[u8], _obj_id: ObjectId) -> Result<Vec<u8>, DecryptionError> {
31 Ok(key.to_vec())
32 }
33
34 fn encrypt(&self, _key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
35 Ok(plaintext.to_vec())
36 }
37
38 fn decrypt(&self, _key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
39 Ok(ciphertext.to_vec())
40 }
41}
42
43#[derive(Clone, Copy, Debug)]
44pub struct Rc4CryptFilter;
45
46impl CryptFilter for Rc4CryptFilter {
47 fn method(&self) -> &[u8] {
48 b"V2"
49 }
50
51 fn compute_key(&self, key: &[u8], obj_id: ObjectId) -> Result<Vec<u8>, DecryptionError> {
52 let mut hasher = Md5::new();
53
54 hasher.update(key);
55
56 hasher.update(&obj_id.0.to_le_bytes()[..3]);
61 hasher.update(&obj_id.1.to_le_bytes()[..2]);
62
63 let key_len = std::cmp::min(key.len() + 5, 16);
69 let key = hasher.finalize()[..key_len].to_vec();
70
71 Ok(key)
72 }
73
74 fn encrypt(&self, key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
75 Ok(Rc4::new(key).encrypt(plaintext))
76 }
77
78 fn decrypt(&self, key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
79 Ok(Rc4::new(key).decrypt(ciphertext))
80 }
81}
82
83#[derive(Clone, Copy, Debug)]
84pub struct Aes128CryptFilter;
85
86impl CryptFilter for Aes128CryptFilter {
87 fn method(&self) -> &[u8] {
88 b"AESV2"
89 }
90
91 fn compute_key(&self, key: &[u8], obj_id: ObjectId) -> Result<Vec<u8>, DecryptionError> {
92 let mut builder = Vec::with_capacity(key.len() + 9);
93
94 builder.extend_from_slice(key);
95
96 builder.extend_from_slice(&obj_id.0.to_le_bytes()[..3]);
101 builder.extend_from_slice(&obj_id.1.to_le_bytes()[..2]);
102
103 builder.extend_from_slice(b"sAlT");
106
107 let key_len = std::cmp::min(key.len() + 5, 16);
113 let key = Md5::digest(builder)[..key_len].to_vec();
114
115 Ok(key)
116 }
117
118 fn encrypt(&self, key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
119 if key.len() != 16 {
121 return Err(DecryptionError::InvalidKeyLength);
122 }
123
124 let ciphertext_len = (plaintext.len() + 16) / 16 * 16;
126
127 let mut ciphertext = Vec::with_capacity(16 + ciphertext_len);
130
131 let mut rng = rand::rng();
133 let mut iv = [0u8; 16];
134 rng.fill(&mut iv);
135
136 ciphertext.extend_from_slice(&iv);
138 ciphertext.extend_from_slice(plaintext);
139 ciphertext.resize(16 + ciphertext_len, 0);
140
141 Aes128CbcEnc::new(key.into(), &iv.into())
148 .encrypt_padded_mut::<Pkcs5>(&mut ciphertext[16..], plaintext.len())
149 .map_err(|_| DecryptionError::Padding)?;
151
152 Ok(ciphertext)
153 }
154
155 fn decrypt(&self, key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
156 if key.len() != 16 {
158 return Err(DecryptionError::InvalidKeyLength);
159 }
160
161 if ciphertext.len() % 16 != 0 {
163 return Err(DecryptionError::InvalidCipherTextLength);
164 }
165
166 if ciphertext.is_empty() || ciphertext.len() == 16 {
168 return Ok(vec![]);
169 }
170
171 let mut iv = [0x00u8; 16];
172 iv.copy_from_slice(&ciphertext[..16]);
173
174 let data = &mut ciphertext[16..].to_vec();
181
182 Ok(Aes128CbcDec::new(key.into(), &iv.into())
183 .decrypt_padded_mut::<Pkcs5>(data)
184 .map_err(|_| DecryptionError::Padding)?
185 .to_vec())
186 }
187}
188
189#[derive(Clone, Copy, Debug)]
190pub struct Aes256CryptFilter;
191
192impl CryptFilter for Aes256CryptFilter {
193 fn method(&self) -> &[u8] {
194 b"AESV3"
195 }
196
197 fn compute_key(&self, key: &[u8], _obj_id: ObjectId) -> Result<Vec<u8>, DecryptionError> {
198 Ok(key.to_vec())
200 }
201
202 fn encrypt(&self, key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
203 if key.len() != 32 {
205 return Err(DecryptionError::InvalidKeyLength);
206 }
207
208 let ciphertext_len = (plaintext.len() + 16) / 16 * 16;
210
211 let mut ciphertext = Vec::with_capacity(16 + ciphertext_len);
214
215 let mut rng = rand::rng();
217 let mut iv = [0u8; 16];
218 rng.fill(&mut iv);
219
220 ciphertext.extend_from_slice(&iv);
222 ciphertext.extend_from_slice(plaintext);
223 ciphertext.resize(16 + ciphertext_len, 0);
224
225 Aes256CbcEnc::new(key.into(), &iv.into())
232 .encrypt_padded_mut::<Pkcs5>(&mut ciphertext[16..], plaintext.len())
233 .map_err(|_| DecryptionError::Padding)?;
235
236 Ok(ciphertext)
237 }
238
239 fn decrypt(&self, key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, DecryptionError> {
240 if key.len() != 32 {
242 return Err(DecryptionError::InvalidKeyLength);
243 }
244
245 if ciphertext.len() % 16 != 0 {
247 return Err(DecryptionError::InvalidCipherTextLength);
248 }
249
250 if ciphertext.is_empty() || ciphertext.len() == 16 {
252 return Ok(vec![]);
253 }
254
255 let mut iv = [0x00u8; 16];
256 iv.copy_from_slice(&ciphertext[..16]);
257
258 let data = &mut ciphertext[16..].to_vec();
265
266 Ok(Aes256CbcDec::new(key.into(), &iv.into())
267 .decrypt_padded_mut::<Pkcs5>(data)
268 .map_err(|_| DecryptionError::Padding)?
269 .to_vec())
270 }
271}