/src/ghostpdl/pdf/pdf_sec.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2020-2025 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | /* PDF decryption routines */ |
17 | | |
18 | | #include "pdf_stack.h" |
19 | | #include "pdf_file.h" |
20 | | #include "pdf_dict.h" |
21 | | #include "pdf_array.h" |
22 | | #include "pdf_sec.h" |
23 | | #include "pdf_misc.h" |
24 | | #include "strmio.h" |
25 | | #include "smd5.h" |
26 | | #include "sarc4.h" |
27 | | #include "aes.h" |
28 | | #include "sha2.h" |
29 | | #include "pdf_utf8.h" |
30 | | #include "pdf_deref.h" |
31 | | |
32 | | /* The padding string as defined in step 1 of Algorithm 3.2 */ |
33 | | static char PadString[32] = { |
34 | | 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, |
35 | | 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a |
36 | | }; |
37 | | |
38 | | /* If EncryptMetadata is true we need to add 4 bytes of 0xFF to the MD5 hash |
39 | | * when computing an encryption key (Algorithm 3.2, step 6 when R is 4 or more) |
40 | | */ |
41 | | static char R4String[4] = { |
42 | | 0xFF, 0xFF, 0xFF, 0xFF |
43 | | }; |
44 | | |
45 | | /* If using the AES filter, we need to add this to the encryption |
46 | | * key when creating the key for decrypting objects (streams or strings) |
47 | | */ |
48 | | static char sAlTString[4] = { |
49 | | 0x73, 0x41, 0x6c, 0x54 |
50 | | }; |
51 | | |
52 | | static int pdf_compute_encryption_key_preR5(pdf_context *ctx, char *Password, int PasswordLen, int KeyLen, pdf_string **EKey, int R) |
53 | 746 | { |
54 | 746 | char Key[32]; |
55 | 746 | int code = 0, KeyLenBytes = KeyLen / 8, i; |
56 | 746 | char P[4]; |
57 | 746 | gs_md5_state_t md5; |
58 | 746 | pdf_array *a = NULL; |
59 | 746 | pdf_string *s = NULL; |
60 | 746 | pdf_dict *d = NULL; |
61 | | |
62 | 746 | *EKey = NULL; |
63 | | /* Algorithm 3.2 */ |
64 | | /* Step 1. Pad or truncate the password string to exactly 32 bytes |
65 | | * using the defined padding string. |
66 | | */ |
67 | 746 | if (PasswordLen > 32) |
68 | 0 | PasswordLen = 32; |
69 | | |
70 | 746 | memcpy(Key, Password, PasswordLen); |
71 | | |
72 | 746 | if (PasswordLen < 32) |
73 | 703 | memcpy(&Key[PasswordLen], PadString, 32 - PasswordLen); |
74 | | |
75 | | /* 2. Initialise the MD5 hash function and pass the result of step 1 to this function */ |
76 | 746 | gs_md5_init(&md5); |
77 | 746 | gs_md5_append(&md5, (gs_md5_byte_t *)&Key, 32); |
78 | | |
79 | | /* 3. Pass the value of the encryption dictionary's O entry to the MD5 hash */ |
80 | 746 | gs_md5_append(&md5, (gs_md5_byte_t *)ctx->encryption.O, 32); |
81 | | |
82 | | /* 4. Treat the value of P as an unsigned 4 byte integer and pass those bytes to the MD5 */ |
83 | 746 | P[3] = ((uint32_t)ctx->encryption.P) >> 24; |
84 | 746 | P[2] = ((uint32_t)ctx->encryption.P & 0x00ff0000) >> 16; |
85 | 746 | P[1] = ((uint32_t)ctx->encryption.P & 0x0000ff00) >> 8; |
86 | 746 | P[0] = ((uint32_t)ctx->encryption.P & 0xff); |
87 | 746 | gs_md5_append(&md5, (gs_md5_byte_t *)P, 4); |
88 | | |
89 | | /* 5. Pass the first element of the file's file identifier array */ |
90 | | /* See comment in pdfi_read_Root() for details of why we indirect through 'd' */ |
91 | 746 | d = ctx->Trailer; |
92 | 746 | pdfi_countup(d); |
93 | 746 | code = pdfi_dict_get_type(ctx, d, "ID", PDF_ARRAY, (pdf_obj **)&a); |
94 | 746 | pdfi_countdown(d); |
95 | 746 | if (code < 0) { |
96 | 2 | if (code == gs_error_undefined) { |
97 | 2 | emprintf(ctx->memory, "\n **** Error: ID key in the trailer is required for encrypted files.\n"); |
98 | 2 | emprintf(ctx->memory, " File may not be possible to decrypt.\n"); |
99 | 2 | } else |
100 | 0 | return code; |
101 | 2 | } |
102 | | /* If the file ID was missing, just ignore the error */ |
103 | 746 | if (code == 0) { |
104 | 744 | code = pdfi_array_get_type(ctx, a, (uint64_t)0, PDF_STRING, (pdf_obj **)&s); |
105 | 744 | if (code < 0) |
106 | 0 | goto done; |
107 | 744 | gs_md5_append(&md5, s->data, s->length); |
108 | 744 | } |
109 | | |
110 | | /* Step 6 |
111 | | * (revision 4 or greater) If document Metadata is not being encrypted |
112 | | * pass 4 bytes with the value 0xFFFFFFFF to the MD5 hash function. |
113 | | */ |
114 | 746 | if (R > 3 && !ctx->encryption.EncryptMetadata) { |
115 | 28 | gs_md5_append(&md5, (const gs_md5_byte_t *)R4String, 4); |
116 | 28 | } |
117 | | |
118 | | /* 7. Finish the hash */ |
119 | 746 | gs_md5_finish(&md5, (gs_md5_byte_t *)&Key); |
120 | | |
121 | 746 | code = pdfi_object_alloc(ctx, PDF_STRING, KeyLenBytes, (pdf_obj **)EKey); |
122 | 746 | if (code < 0) |
123 | 0 | goto done; |
124 | 746 | pdfi_countup((pdf_obj *)*EKey); |
125 | | |
126 | | /* Step 8 |
127 | | * (revision 3 or greater) Do the following 50 times. Take the output from the |
128 | | * previous MD5 hash and pass hte first n bytes of the output as input to a new |
129 | | * MD5 hash, where n is the number of bytes of the encryption key as defined by |
130 | | * the value of the encryption dictionary's Length entry. (NB Length is in bits) |
131 | | */ |
132 | 746 | if (R > 2) { |
133 | 25.7k | for (i=0;i < 50; i++) { |
134 | 25.2k | memcpy((*EKey)->data, Key, KeyLenBytes); |
135 | 25.2k | gs_md5_init(&md5); |
136 | 25.2k | gs_md5_append(&md5, (gs_md5_byte_t *)(*EKey)->data, KeyLenBytes); |
137 | 25.2k | gs_md5_finish(&md5, (gs_md5_byte_t *)&Key); |
138 | 25.2k | } |
139 | 504 | } |
140 | | |
141 | | /* Step 9 |
142 | | * Set the encryption key to the first n bytes of the output from the final MD5 hash |
143 | | * where n is always 5 for revision 2 but, for revision 3 or greater, depends on the |
144 | | * value of the encryption dictionary's Length entry. |
145 | | */ |
146 | 746 | memcpy((*EKey)->data, Key, KeyLenBytes); |
147 | | |
148 | 746 | done: |
149 | 746 | pdfi_countdown(s); |
150 | 746 | pdfi_countdown(a); |
151 | 746 | return code; |
152 | 746 | } |
153 | | |
154 | | #ifdef HAVE_LIBIDN |
155 | | # include <stringprep.h> |
156 | | |
157 | | static int apply_sasl(pdf_context *ctx, char *Password, int Len, char **NewPassword, int *NewLen) |
158 | | { |
159 | | byte *buffer; |
160 | | uint buffer_size; |
161 | | Stringprep_rc err; |
162 | | |
163 | | buffer_size = Len * 11 + 1; |
164 | | buffer = (byte *)gs_alloc_bytes(ctx->memory, buffer_size, "saslprep result"); |
165 | | if (buffer == NULL) |
166 | | return_error(gs_error_VMerror); |
167 | | |
168 | | err = stringprep((char *)buffer, buffer_size, 0, stringprep_saslprep); |
169 | | if (err != STRINGPREP_OK) { |
170 | | gs_free_object(ctx->memory, buffer, "saslprep result"); |
171 | | |
172 | | /* Since we're just verifying the password to an existing |
173 | | * document here, we don't care about "invalid input" errors |
174 | | * like STRINGPREP_CONTAINS_PROHIBITED. In these cases, we |
175 | | * ignore the error and return the original string unchanged -- |
176 | | * chances are it's not the right password anyway, and if it |
177 | | * is we shouldn't gratuitously fail to decrypt the document. |
178 | | * |
179 | | * On the other hand, errors like STRINGPREP_NFKC_FAILED are |
180 | | * real errors, and should be returned to the user. |
181 | | * |
182 | | * Fortunately, the stringprep error codes are sorted to make |
183 | | * this easy: the errors we want to ignore are the ones with |
184 | | * codes less than 100. */ |
185 | | if ((int)err < 100) { |
186 | | *NewPassword = Password; |
187 | | *NewLen = Len; |
188 | | return 0; |
189 | | } |
190 | | |
191 | | return_error(gs_error_ioerror); |
192 | | } |
193 | | |
194 | | *NewLen = strlen((char *)buffer); |
195 | | *NewPassword = (char *)buffer; |
196 | | |
197 | | return 0; |
198 | | |
199 | | } |
200 | | #endif |
201 | | |
202 | | static int check_user_password_R5(pdf_context *ctx, char *Password, int Len, int KeyLen) |
203 | 0 | { |
204 | 0 | char *UTF8_Password = NULL, *Test = NULL, Buffer[32], UEPadded[48]; |
205 | 0 | int NewLen; |
206 | 0 | int code = 0; |
207 | 0 | pdf_c_stream *stream = NULL, *filter_stream = NULL; |
208 | 0 | pdf_string *Key = NULL; |
209 | 0 | SHA256_CTX sha256; |
210 | | |
211 | | /* Algorithm 3.11 from the Adobe extensions to the ISO 32000 specification (Extension Level 3) */ |
212 | | /* Step 1 convert the password to UTF-8 */ |
213 | | |
214 | | /* From the original code in Resource/Init/pdf_sec.ps: |
215 | | * Step 1. |
216 | | * If the .saslprep operator isn't available (because ghostscript |
217 | | * wasn't built with libidn support), just skip this step. ASCII |
218 | | * passwords will still work fine, and even most non-ASCII passwords |
219 | | * will be okay; any non-ASCII passwords that fail will produce a |
220 | | * warning from pdf_process_Encrypt. |
221 | | */ |
222 | | #ifdef HAVE_LIBIDN |
223 | | code = apply_sasl(ctx, Password, Len, &UTF8_Password, &NewLen); |
224 | | if (code < 0) |
225 | | return code; |
226 | | #else |
227 | 0 | UTF8_Password = Password; |
228 | 0 | NewLen = Len; |
229 | 0 | #endif |
230 | 0 | if (NewLen > 127) |
231 | 0 | NewLen = 127; |
232 | |
|
233 | 0 | Test = (char *)gs_alloc_bytes(ctx->memory, NewLen + 8, "R5 password test"); |
234 | 0 | if (Test == NULL) { |
235 | 0 | code = gs_note_error(gs_error_VMerror); |
236 | 0 | goto error; |
237 | 0 | } |
238 | | |
239 | | /* Try to validate the password as the user password */ |
240 | | /* concatenate the password */ |
241 | 0 | memcpy(Test, UTF8_Password, NewLen); |
242 | | /* With the 'User Validation Salt' (stored as part of the /O string */ |
243 | 0 | memcpy(&Test[NewLen], &ctx->encryption.U[32], 8); |
244 | |
|
245 | 0 | pSHA256_Init(&sha256); |
246 | 0 | pSHA256_Update(&sha256, (uint8_t *)Test, NewLen + 8); |
247 | 0 | pSHA256_Final((uint8_t *)Buffer, &sha256); |
248 | |
|
249 | 0 | if (memcmp(Buffer, ctx->encryption.U, 32) != 0) { |
250 | 0 | code = gs_note_error(gs_error_unknownerror); |
251 | 0 | goto error; |
252 | 0 | } |
253 | | |
254 | | /* Password matched */ |
255 | | /* Finally calculate the decryption key */ |
256 | 0 | gs_free_object(ctx->memory, Test, "R5 password test"); |
257 | | |
258 | | /* Password + last 8 bytes of /U */ |
259 | 0 | Test = (char *)gs_alloc_bytes(ctx->memory, NewLen + 8, "R5 password test"); |
260 | 0 | if (Test == NULL) { |
261 | 0 | code = gs_note_error(gs_error_VMerror); |
262 | 0 | goto error; |
263 | 0 | } |
264 | | |
265 | 0 | memcpy(Test, UTF8_Password, NewLen); |
266 | | /* The 'User Key Salt' (stored as part of the /O string */ |
267 | 0 | memcpy(&Test[NewLen], &ctx->encryption.U[40], 8); |
268 | |
|
269 | 0 | pSHA256_Init(&sha256); |
270 | 0 | pSHA256_Update(&sha256, (uint8_t *)Test, NewLen + 8); |
271 | 0 | pSHA256_Final((uint8_t *)Buffer, &sha256); |
272 | |
|
273 | 0 | memset(UEPadded, 0x00, 16); |
274 | 0 | memcpy(&UEPadded[16], ctx->encryption.UE, 32); |
275 | |
|
276 | 0 | code = pdfi_object_alloc(ctx, PDF_STRING, 32, (pdf_obj **)&Key); |
277 | 0 | if (code < 0) |
278 | 0 | goto error; |
279 | | /* pdfi_object_alloc() creates objects with a refrence count of 0 */ |
280 | 0 | pdfi_countup(Key); |
281 | 0 | memcpy(Key->data, Buffer, 32); |
282 | | |
283 | | /* Now apply AESDecode to the padded UE string, using the SHA from above as the key */ |
284 | 0 | code = pdfi_open_memory_stream_from_memory(ctx, 48, (byte *)UEPadded, &stream, true); |
285 | 0 | if (code < 0) |
286 | 0 | goto error; |
287 | | |
288 | 0 | code = pdfi_apply_AES_filter(ctx, Key, false, stream, &filter_stream); |
289 | 0 | if (code < 0) { |
290 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
291 | 0 | goto error; |
292 | 0 | } |
293 | | |
294 | 0 | sfread(Buffer, 1, 32, filter_stream->s); |
295 | 0 | pdfi_close_file(ctx, filter_stream); |
296 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
297 | 0 | code = pdfi_object_alloc(ctx, PDF_STRING, 32, (pdf_obj **)&ctx->encryption.EKey); |
298 | 0 | if (code < 0) |
299 | 0 | goto error; |
300 | 0 | memcpy(ctx->encryption.EKey->data, Buffer, 32); |
301 | 0 | pdfi_countup(ctx->encryption.EKey); |
302 | |
|
303 | 0 | error: |
304 | 0 | pdfi_countdown(Key); |
305 | 0 | gs_free_object(ctx->memory, Test, "R5 password test"); |
306 | | #ifdef HAVE_LIBIDN |
307 | | if (UTF8_Password != Password) |
308 | | gs_free_object(ctx->memory, UTF8_Password, "free sasl result"); |
309 | | #endif |
310 | 0 | return code; |
311 | 0 | } |
312 | | |
313 | | /* Implementation of the PDF security handler revision6 (PDF 1.7 ExtensionLevel 8 algorithm) |
314 | | * |
315 | | * Adobe/ISO has not yet released the details, so the algorithm reference is: |
316 | | * http://esec-lab.sogeti.com/post/The-undocumented-password-validation-algorithm-of-Adobe-Reader-X |
317 | | * |
318 | | * The code below is the same as (and copied from) the MuPDF implementation. And copied from the |
319 | | * Ghostscript implementation in zpdf_r6.c. The ISO specification is now released and the algorithms |
320 | | * used here are documented in the PDF 2.0 specification ISO 32000-2:2017 |
321 | | */ |
322 | | |
323 | | static void |
324 | | pdf_compute_hardened_hash_r6(unsigned char *password, int pwlen, unsigned char *salt, unsigned char *ownerkey, unsigned char *hash) |
325 | 1.07k | { |
326 | 1.07k | unsigned char data[(128 + 64 + 48) * 64]; |
327 | 1.07k | unsigned char block[64]; |
328 | 1.07k | int block_size = 32; |
329 | 1.07k | int data_len = 0; |
330 | 1.07k | int i, j, sum; |
331 | | |
332 | 1.07k | SHA256_CTX sha256; |
333 | 1.07k | SHA384_CTX sha384; |
334 | 1.07k | SHA512_CTX sha512; |
335 | 1.07k | aes_context aes; |
336 | | |
337 | 1.07k | pSHA256_Init(&sha256); |
338 | 1.07k | pSHA256_Update(&sha256, password, pwlen); |
339 | 1.07k | pSHA256_Update(&sha256, salt, 8); |
340 | 1.07k | if (ownerkey) |
341 | 358 | pSHA256_Update(&sha256, ownerkey, 48); |
342 | 1.07k | pSHA256_Final((uint8_t *)block, &sha256); |
343 | | |
344 | 73.8k | for (i = 0; i < 64 || i < data[data_len * 64 - 1] + 32; i++) |
345 | 72.7k | { |
346 | | /* Step 2: repeat password and data block 64 times */ |
347 | 72.7k | memcpy(data, password, pwlen); |
348 | 72.7k | memcpy(data + pwlen, block, block_size); |
349 | 72.7k | if (ownerkey) |
350 | 24.2k | memcpy(data + pwlen + block_size, ownerkey, 48); |
351 | 72.7k | data_len = pwlen + block_size + (ownerkey ? 48 : 0); |
352 | 4.65M | for (j = 1; j < 64; j++) |
353 | 4.58M | memcpy(data + j * data_len, data, data_len); |
354 | | |
355 | | /* Step 3: encrypt data using data block as key and iv */ |
356 | 72.7k | aes_setkey_enc(&aes, block, 128); |
357 | 72.7k | aes_crypt_cbc(&aes, AES_ENCRYPT, data_len * 64, block + 16, data, data); |
358 | | |
359 | | /* Step 4: determine SHA-2 hash size for this round */ |
360 | 1.23M | for (j = 0, sum = 0; j < 16; j++) |
361 | 1.16M | sum += data[j]; |
362 | | |
363 | | /* Step 5: calculate data block for next round */ |
364 | 72.7k | block_size = 32 + (sum % 3) * 16; |
365 | 72.7k | switch (block_size) |
366 | 72.7k | { |
367 | 25.5k | case 32: |
368 | 25.5k | pSHA256_Init(&sha256); |
369 | 25.5k | pSHA256_Update(&sha256, data, data_len * 64); |
370 | 25.5k | pSHA256_Final((uint8_t *)block, &sha256); |
371 | 25.5k | break; |
372 | 22.7k | case 48: |
373 | 22.7k | pSHA384_Init(&sha384); |
374 | 22.7k | pSHA384_Update(&sha384, data, data_len * 64); |
375 | 22.7k | pSHA384_Final((uint8_t *)block, &sha384); |
376 | 22.7k | break; |
377 | 24.4k | case 64: |
378 | 24.4k | pSHA512_Init(&sha512); |
379 | 24.4k | pSHA512_Update(&sha512, data, data_len * 64); |
380 | 24.4k | pSHA512_Final((uint8_t *)block, &sha512); |
381 | 24.4k | break; |
382 | 72.7k | } |
383 | 72.7k | } |
384 | | |
385 | 1.07k | memset(data, 0, sizeof(data)); |
386 | 1.07k | memcpy(hash, block, 32); |
387 | 1.07k | } |
388 | | |
389 | | static void |
390 | | pdf_compute_encryption_key_r6(unsigned char *password, int pwlen, unsigned char *O, unsigned char *OE, unsigned char *U, unsigned char *UE, int ownerkey, unsigned char *validationkey, unsigned char *output) |
391 | 535 | { |
392 | 535 | unsigned char hash[32]; |
393 | 535 | unsigned char iv[16]; |
394 | 535 | aes_context aes; |
395 | | |
396 | 535 | if (pwlen > 127) |
397 | 0 | pwlen = 127; |
398 | | |
399 | 535 | pdf_compute_hardened_hash_r6(password, pwlen, |
400 | 535 | (ownerkey ? O : U) + 32, |
401 | 535 | ownerkey ? U : NULL, validationkey); |
402 | 535 | pdf_compute_hardened_hash_r6(password, pwlen, |
403 | 535 | (ownerkey ? O : U) + 40, |
404 | 535 | (ownerkey ? U : NULL), hash); |
405 | | |
406 | 535 | memset(iv, 0, sizeof(iv)); |
407 | 535 | aes_setkey_dec(&aes, hash, 256); |
408 | 535 | aes_crypt_cbc(&aes, AES_DECRYPT, 32, iv, |
409 | 535 | ownerkey ? OE : UE, output); |
410 | 535 | } |
411 | | |
412 | | static int check_user_password_R6(pdf_context *ctx, char *Password, int Len, int KeyLen) |
413 | 356 | { |
414 | 356 | unsigned char validation[32]; |
415 | 356 | unsigned char output[32]; |
416 | 356 | int code = 0; |
417 | | |
418 | 356 | pdf_compute_encryption_key_r6((unsigned char *)Password, Len, (unsigned char *)ctx->encryption.O, (unsigned char *)ctx->encryption.OE, |
419 | 356 | (unsigned char *)ctx->encryption.U, (unsigned char *)ctx->encryption.UE, 0, validation, output); |
420 | | |
421 | 356 | if (memcmp(validation, ctx->encryption.U, 32) != 0) |
422 | 179 | return_error(gs_error_unknownerror); |
423 | | |
424 | 177 | code = pdfi_object_alloc(ctx, PDF_STRING, 32, (pdf_obj **)&ctx->encryption.EKey); |
425 | 177 | if (code < 0) |
426 | 177 | return_error(gs_error_VMerror);; |
427 | 177 | memcpy(ctx->encryption.EKey->data, output, 32); |
428 | 177 | pdfi_countup(ctx->encryption.EKey); |
429 | | |
430 | 177 | return 0; |
431 | 177 | } |
432 | | |
433 | | static int check_user_password_preR5(pdf_context *ctx, char *Password, int Len, int KeyLen, int R) |
434 | 746 | { |
435 | 746 | pdf_string *Key = NULL, *XORKey = NULL; |
436 | 746 | int code = 0, i, j, KeyLenBytes = KeyLen / 8; |
437 | 746 | pdf_c_stream *stream, *arc4_stream; |
438 | 746 | char Buffer[32]; |
439 | 746 | char Hash[16]; |
440 | 746 | gs_md5_state_t md5; |
441 | 746 | pdf_string *s = NULL; |
442 | 746 | pdf_array *a = NULL; |
443 | 746 | pdf_dict *d = NULL; |
444 | | |
445 | | /* Algorithm 3.6, step 1 |
446 | | * perform all but the last step of Algorithm 3,4 (Revision 2) |
447 | | * or Algorithm 3.5 (revision 3 or greater). |
448 | | */ |
449 | | |
450 | | /* Algorithm 3.4 step 1 |
451 | | * Create an encryption key based on the user password string as described in Algorithm 3.2 |
452 | | */ |
453 | 746 | code = pdf_compute_encryption_key_preR5(ctx, Password, Len, KeyLen, &Key, R); |
454 | 746 | if (code < 0) |
455 | 0 | return code; |
456 | | |
457 | 746 | switch (R) { |
458 | 242 | case 2: |
459 | | /* Algorithm 3.4, step 2 |
460 | | * Encrypt the 32 byte padding string from step 1 of Algorithm 3.2, with an RC4 |
461 | | * encryption function, using the key from the preceding step. |
462 | | */ |
463 | | |
464 | 242 | code = pdfi_open_memory_stream_from_memory(ctx, 32, (byte *)PadString, &stream, true); |
465 | 242 | if (code < 0) |
466 | 0 | goto error; |
467 | | |
468 | 242 | code = pdfi_apply_Arc4_filter(ctx, Key, stream, &arc4_stream); |
469 | 242 | if (code < 0) { |
470 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
471 | 0 | goto error; |
472 | 0 | } |
473 | | |
474 | 242 | sfread(Buffer, 1, 32, arc4_stream->s); |
475 | 242 | pdfi_close_file(ctx, arc4_stream); |
476 | 242 | pdfi_close_memory_stream(ctx, NULL, stream); |
477 | | |
478 | | /* Algorithm 3.6 step 2 |
479 | | * If the result of the step above is equal to the value of the encryption dictionary |
480 | | * U entry the password supplied is the correct user password. |
481 | | */ |
482 | 242 | if (memcmp(Buffer, ctx->encryption.U, 32) != 0) { |
483 | 22 | code = gs_error_unknownerror; |
484 | 22 | goto error; |
485 | 220 | } else { |
486 | | /* Password authenticated, we can now use the calculated encryption key to decrypt the file */ |
487 | 220 | ctx->encryption.EKey = Key; |
488 | 220 | } |
489 | 220 | break; |
490 | 220 | case 3: |
491 | 504 | case 4: |
492 | | /* Algorithm 3.5 step 2 |
493 | | * Pass the 32 byte padding string from step 1 of Algorithm 3.2 to an MD5 hash */ |
494 | 504 | gs_md5_init(&md5); |
495 | 504 | gs_md5_append(&md5, (gs_md5_byte_t *)PadString, 32); |
496 | | /* See comment in pdfi_read_Root() for details of why we indirect through 'd' */ |
497 | 504 | d = ctx->Trailer; |
498 | 504 | pdfi_countup(d); |
499 | 504 | code = pdfi_dict_get_type(ctx, d, "ID", PDF_ARRAY, (pdf_obj **)&a); |
500 | 504 | pdfi_countdown(d); |
501 | 504 | if (code < 0) { |
502 | 0 | if (code == gs_error_undefined) { |
503 | 0 | emprintf(ctx->memory, "\n **** Error: ID key in the trailer is required for encrypted files.\n"); |
504 | 0 | emprintf(ctx->memory, " File may not be possible to decrypt.\n"); |
505 | 0 | } else |
506 | 0 | return code; |
507 | 0 | } |
508 | 504 | if (code == 0) { |
509 | | /* Step 3 |
510 | | * Pass the first element of the file's file identifier array to the hash function |
511 | | * and finish the hash |
512 | | */ |
513 | 504 | code = pdfi_array_get_type(ctx, a, (uint64_t)0, PDF_STRING, (pdf_obj **)&s); |
514 | 504 | if (code < 0) |
515 | 0 | goto error; |
516 | 504 | gs_md5_append(&md5, s->data, s->length); |
517 | 504 | } |
518 | 504 | gs_md5_finish(&md5, (gs_md5_byte_t *)&Hash); |
519 | | |
520 | | /* Step 4 |
521 | | * Encrypt the 16-byte result of the hash using an RC4 encryption function with |
522 | | * the encryption key from step 1 (of Algorithm 3.5). |
523 | | */ |
524 | 504 | code = pdfi_open_memory_stream_from_memory(ctx, 16, (byte *)Hash, &stream, true); |
525 | 504 | if (code < 0) |
526 | 0 | goto error; |
527 | | |
528 | 504 | code = pdfi_apply_Arc4_filter(ctx, Key, stream, &arc4_stream); |
529 | 504 | if (code < 0) { |
530 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
531 | 0 | goto error; |
532 | 0 | } |
533 | | |
534 | 504 | sfread(Buffer, 1, 16, arc4_stream->s); |
535 | 504 | pdfi_close_file(ctx, arc4_stream); |
536 | 504 | pdfi_close_memory_stream(ctx, NULL, stream); |
537 | | |
538 | 504 | code = pdfi_object_alloc(ctx, PDF_STRING, KeyLenBytes, (pdf_obj **)&XORKey); |
539 | 504 | if (code < 0) |
540 | 0 | goto error; |
541 | | /* pdfi_object_alloc() creates objects with a reference count of 0 */ |
542 | 504 | pdfi_countup(XORKey); |
543 | | |
544 | | /* Step 5 |
545 | | * Do the following 19 times. Take the output from the previous invocation of the RC4 |
546 | | * function and pas it as input to a new invocation of the function; use an encryption key |
547 | | * generated by taking each byte of the original encyption key (obtained in step 1 of |
548 | | * algorithm 3.5) and performing an XOR operation between that byte and the single byte |
549 | | * value of the iteration counter (from 1 to 19). |
550 | | */ |
551 | 10.0k | for (i=1;i < 20;i++) { |
552 | 9.57k | memcpy(Hash, Buffer, 16); |
553 | 9.57k | code = pdfi_open_memory_stream_from_memory(ctx, 16, (byte *)Hash, &stream, true); |
554 | 9.57k | if (code < 0) |
555 | 0 | goto error; |
556 | | |
557 | 160k | for (j=0;j < KeyLenBytes;j++) { |
558 | 150k | XORKey->data[j] = Key->data[j] ^ i; |
559 | 150k | } |
560 | | |
561 | 9.57k | code = pdfi_apply_Arc4_filter(ctx, XORKey, stream, &arc4_stream); |
562 | 9.57k | if (code < 0) { |
563 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
564 | 0 | goto error; |
565 | 0 | } |
566 | 9.57k | sfread(Buffer, 1, 16, arc4_stream->s); |
567 | 9.57k | pdfi_close_file(ctx, arc4_stream); |
568 | 9.57k | pdfi_close_memory_stream(ctx, NULL, stream); |
569 | 9.57k | } |
570 | | |
571 | | /* Algorithm 3.6 step 2 |
572 | | * If the result of the step above is equal to the value of the encryption dictionary U entry |
573 | | * (comparing on the first 16 bytes in the case of revision 3 of greater) |
574 | | * the password supplied is the correct user password. |
575 | | */ |
576 | 504 | if (memcmp(Buffer, ctx->encryption.U, 16) != 0) { |
577 | 64 | code = gs_error_unknownerror; |
578 | 64 | goto error; |
579 | 440 | } else { |
580 | | /* Password authenticated, we can now use the calculated encryption key to decrypt the file */ |
581 | 440 | ctx->encryption.EKey = Key; |
582 | 440 | } |
583 | 440 | break; |
584 | 440 | default: |
585 | 0 | code = gs_note_error(gs_error_rangecheck); |
586 | 0 | goto error; |
587 | 0 | break; |
588 | 746 | } |
589 | | |
590 | | /* We deliberately don't countdown Key here, if we created it and there were no |
591 | | * errors then we will have stored it in the global context for future use. It |
592 | | * will be counted down when the context is destroyed. |
593 | | */ |
594 | 660 | pdfi_countdown(XORKey); |
595 | 660 | pdfi_countdown(s); |
596 | 660 | pdfi_countdown(a); |
597 | 660 | return 0; |
598 | | |
599 | 86 | error: |
600 | 86 | pdfi_countdown(XORKey); |
601 | 86 | pdfi_countdown(Key); |
602 | 86 | pdfi_countdown(s); |
603 | 86 | pdfi_countdown(a); |
604 | 86 | return code; |
605 | 746 | } |
606 | | |
607 | | static int check_owner_password_R5(pdf_context *ctx, char *Password, int Len, int KeyLen) |
608 | 0 | { |
609 | 0 | char *UTF8_Password = NULL, *Test = NULL, Buffer[32], OEPadded[48]; |
610 | 0 | int NewLen; |
611 | 0 | int code = 0; |
612 | 0 | pdf_c_stream *stream = NULL, *filter_stream = NULL; |
613 | 0 | pdf_string *Key = NULL; |
614 | 0 | SHA256_CTX sha256; |
615 | | |
616 | | /* From the original code in Resource/Init/pdf_sec.ps: |
617 | | * Step 1. |
618 | | * If the .saslprep operator isn't available (because ghostscript |
619 | | * wasn't built with libidn support), just skip this step. ASCII |
620 | | * passwords will still work fine, and even most non-ASCII passwords |
621 | | * will be okay; any non-ASCII passwords that fail will produce a |
622 | | * warning from pdf_process_Encrypt. |
623 | | */ |
624 | | #ifdef HAVE_LIBIDN |
625 | | code = apply_sasl(ctx, Password, Len, &UTF8_Password, &NewLen); |
626 | | if (code < 0) |
627 | | return code; |
628 | | #else |
629 | 0 | UTF8_Password = Password; |
630 | 0 | NewLen = Len; |
631 | 0 | #endif |
632 | 0 | if (NewLen > 127) |
633 | 0 | NewLen = 127; |
634 | |
|
635 | 0 | Test = (char *)gs_alloc_bytes(ctx->memory, NewLen + 8 + 48, "r5 password test"); |
636 | 0 | if (Test == NULL) { |
637 | 0 | code = gs_note_error(gs_error_VMerror); |
638 | 0 | goto error; |
639 | 0 | } |
640 | | |
641 | | /* concatenate the password */ |
642 | 0 | memcpy(Test, UTF8_Password, NewLen); |
643 | | /* With the 'Owner Validation Salt' (stored as part of the /O string */ |
644 | 0 | memcpy(&Test[NewLen], &ctx->encryption.O[32], 8); |
645 | | /* and also concatenated with the /U string, which is defined to be 48 bytes for revision 5 */ |
646 | 0 | memcpy(&Test[NewLen + 8], &ctx->encryption.U, 48); |
647 | | |
648 | | /* Now calculate the SHA256 hash */ |
649 | 0 | pSHA256_Init(&sha256); |
650 | 0 | pSHA256_Update(&sha256, (const uint8_t *)Test, NewLen + 8 + 48); |
651 | 0 | pSHA256_Final((uint8_t *)Buffer, &sha256); |
652 | |
|
653 | 0 | if (memcmp(Buffer, ctx->encryption.O, 32) != 0) { |
654 | 0 | code = gs_note_error(gs_error_unknownerror); |
655 | 0 | goto error; |
656 | 0 | } |
657 | | |
658 | | /* Password matched */ |
659 | | /* Finally calculate the decryption key */ |
660 | 0 | gs_free_object(ctx->memory, Test, "R5 password test"); |
661 | | |
662 | | /* Password + last 8 bytes of /O */ |
663 | 0 | Test = (char *)gs_alloc_bytes(ctx->memory, NewLen + 8 + 48, "R5 password test"); |
664 | 0 | if (Test == NULL) { |
665 | 0 | code = gs_note_error(gs_error_VMerror); |
666 | 0 | goto error; |
667 | 0 | } |
668 | | |
669 | 0 | memcpy(Test, UTF8_Password, NewLen); |
670 | | /* The 'User Key Salt' (stored as part of the /O string */ |
671 | 0 | memcpy(&Test[NewLen], &ctx->encryption.O[40], 8); |
672 | 0 | memcpy(&Test[NewLen + 8], ctx->encryption.U, 48); |
673 | | |
674 | | /* Now calculate the SHA256 hash */ |
675 | 0 | pSHA256_Init(&sha256); |
676 | 0 | pSHA256_Update(&sha256, (const uint8_t *)Test, NewLen + 8 + 48); |
677 | 0 | pSHA256_Final((uint8_t *)Buffer, &sha256); |
678 | |
|
679 | 0 | memset(OEPadded, 0x00, 16); |
680 | 0 | memcpy(&OEPadded[16], ctx->encryption.OE, 32); |
681 | |
|
682 | 0 | code = pdfi_object_alloc(ctx, PDF_STRING, 32, (pdf_obj **)&Key); |
683 | 0 | if (code < 0) |
684 | 0 | goto error; |
685 | | /* pdfi_object_alloc() creates objects with a refrence count of 0 */ |
686 | 0 | pdfi_countup(Key); |
687 | 0 | memcpy(Key->data, Buffer, 32); |
688 | | |
689 | | /* Now apply AESDecode to the padded UE string, using the SHA from above as the key */ |
690 | 0 | code = pdfi_open_memory_stream_from_memory(ctx, 48, (byte *)OEPadded, &stream, true); |
691 | 0 | if (code < 0) |
692 | 0 | goto error; |
693 | | |
694 | 0 | code = pdfi_apply_AES_filter(ctx, Key, false, stream, &filter_stream); |
695 | 0 | if (code < 0) { |
696 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
697 | 0 | goto error; |
698 | 0 | } |
699 | | |
700 | 0 | sfread(Buffer, 1, 32, filter_stream->s); |
701 | 0 | pdfi_close_file(ctx, filter_stream); |
702 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
703 | 0 | code = pdfi_object_alloc(ctx, PDF_STRING, 32, (pdf_obj **)&ctx->encryption.EKey); |
704 | 0 | if (code < 0) |
705 | 0 | goto error; |
706 | 0 | memcpy(ctx->encryption.EKey->data, Buffer, 32); |
707 | 0 | pdfi_countup(ctx->encryption.EKey); |
708 | |
|
709 | 0 | error: |
710 | 0 | pdfi_countdown(Key); |
711 | 0 | gs_free_object(ctx->memory, Test, "R5 password test"); |
712 | | #ifdef HAVE_LIBIDN |
713 | | if (UTF8_Password != Password) |
714 | | gs_free_object(ctx->memory, UTF8_Password, "free sasl result"); |
715 | | #endif |
716 | 0 | return code; |
717 | 0 | } |
718 | | |
719 | | static int check_owner_password_R6(pdf_context *ctx, char *Password, int Len, int KeyLen) |
720 | 179 | { |
721 | 179 | unsigned char validation[32]; |
722 | 179 | unsigned char output[32]; |
723 | 179 | int code = 0; |
724 | | |
725 | 179 | pdf_compute_encryption_key_r6((unsigned char *)Password, Len, (unsigned char *)ctx->encryption.O, (unsigned char *)ctx->encryption.OE, |
726 | 179 | (unsigned char *)ctx->encryption.U, (unsigned char *)ctx->encryption.UE, 1, validation, output); |
727 | | |
728 | 179 | if (memcmp(validation, ctx->encryption.O, 32) != 0) |
729 | 76 | return_error(gs_error_unknownerror); |
730 | | |
731 | 103 | code = pdfi_object_alloc(ctx, PDF_STRING, 32, (pdf_obj **)&ctx->encryption.EKey); |
732 | 103 | if (code < 0) |
733 | 103 | return_error(gs_error_VMerror);; |
734 | 103 | memcpy(ctx->encryption.EKey->data, output, 32); |
735 | 103 | pdfi_countup(ctx->encryption.EKey); |
736 | | |
737 | 103 | return 0; |
738 | 103 | } |
739 | | |
740 | | static int check_owner_password_preR5(pdf_context *ctx, char *Password, int Len, int KeyLen, int R) |
741 | 43 | { |
742 | 43 | char Key[32]; |
743 | 43 | int code = 0, i, j, KeyLenBytes = KeyLen / 8; |
744 | 43 | pdf_string *EKey = NULL; |
745 | 43 | gs_md5_state_t md5; |
746 | 43 | pdf_c_stream *stream, *arc4_stream; |
747 | 43 | char Buffer[32], Arc4Source[32]; |
748 | | |
749 | | /* Algorithm 3.7 */ |
750 | | /* Step 1, Compute an encryption key from steps 1-4 of Algorithm 3.3 */ |
751 | | |
752 | | /* Algorithm 3.3, step 1. Pad or truncate the password string to exactly 32 bytes */ |
753 | 43 | if (Len > 32) |
754 | 0 | Len = 32; |
755 | | |
756 | 43 | memcpy(Key, Password, Len); |
757 | | |
758 | 43 | if (Len < 32) |
759 | 43 | memcpy(&Key[Len], PadString, 32 - Len); |
760 | | |
761 | | /* Algorithm 3.3, step 2. Initialise the MD5 hash function and pass the result of step 1 to this function */ |
762 | 43 | gs_md5_init(&md5); |
763 | 43 | gs_md5_append(&md5, (gs_md5_byte_t *)&Key, 32); |
764 | 43 | gs_md5_finish(&md5, (gs_md5_byte_t *)&Key); |
765 | | |
766 | | /* Algorithm 3.3, step 3. Only for R3 or greater */ |
767 | 43 | if (R > 2) { |
768 | 32 | code = pdfi_object_alloc(ctx, PDF_STRING, KeyLenBytes, (pdf_obj **)&EKey); |
769 | 32 | if (code < 0) |
770 | 0 | goto error; |
771 | | /* pdfi_object_alloc() creates objects with a refrence count of 0 */ |
772 | 32 | pdfi_countup(EKey); |
773 | | |
774 | 1.63k | for (i = 0; i < 50; i++) { |
775 | 1.60k | gs_md5_init(&md5); |
776 | 1.60k | gs_md5_append(&md5, (gs_md5_byte_t *)&Key, KeyLenBytes); |
777 | 1.60k | gs_md5_finish(&md5, (gs_md5_byte_t *)&Key); |
778 | 1.60k | } |
779 | | /* Algorithm 3.3, step 4. Use KeyLen bytes of the final hash as an RC$ key */ |
780 | | /* Algorithm 3.7, step 2 (R >= 3) */ |
781 | 32 | memcpy(Buffer, ctx->encryption.O, 32); |
782 | | |
783 | | /* Algorithm 3.7 states (at the end): |
784 | | * "performing an XOR (exclusive or) operation between each byte of the key and the single-byte value of the iteration counter (from 19 to 0)." |
785 | | * which implies that the loop should run 20 times couting down from 19 to 0. For decryption at least this is completely |
786 | | * incorrect. Doing that results in completely garbage output. |
787 | | * By using 0 as the first index we get the correct Key when XOR'ing that with the |
788 | | * key computed above, and continuing until the loop counter reaches 19 gives us the correct |
789 | | * result. |
790 | | */ |
791 | 672 | for (i=0; i<20; i++) { |
792 | 640 | memcpy(Arc4Source, Buffer, 32); |
793 | 640 | code = pdfi_open_memory_stream_from_memory(ctx, 32, (byte *)Arc4Source, &stream, true); |
794 | 640 | if (code < 0) |
795 | 0 | goto error; |
796 | 9.56k | for(j=0;j< KeyLenBytes;j++){ |
797 | 8.92k | EKey->data[j] = Key[j] ^ i; |
798 | 8.92k | } |
799 | 640 | code = pdfi_apply_Arc4_filter(ctx, EKey, stream, &arc4_stream); |
800 | 640 | sfread(Buffer, 1, 32, arc4_stream->s); |
801 | 640 | pdfi_close_file(ctx, arc4_stream); |
802 | 640 | pdfi_close_memory_stream(ctx, NULL, stream); |
803 | 640 | } |
804 | | |
805 | 32 | } else { |
806 | | /* Algorithm 3.3, step 4. For revision 2 always use 5 bytes of the final hash as an RC4 key */ |
807 | 11 | code = pdfi_object_alloc(ctx, PDF_STRING, 5, (pdf_obj **)&EKey); |
808 | 11 | if (code < 0) |
809 | 0 | goto error; |
810 | 11 | pdfi_countup(EKey); |
811 | 11 | memcpy(EKey->data, Key, 5); |
812 | | |
813 | | /* Algorithm 3.7, step 2 (R == 2) Use RC4 with the computed key to decrypt the O entry of the crypt dict */ |
814 | 11 | code = pdfi_open_memory_stream_from_memory(ctx, 32, (byte *)ctx->encryption.O, &stream, true); |
815 | 11 | if (code < 0) |
816 | 0 | goto error; |
817 | | |
818 | 11 | code = pdfi_apply_Arc4_filter(ctx, EKey, stream, &arc4_stream); |
819 | 11 | pdfi_countdown(EKey); |
820 | 11 | EKey = NULL; |
821 | | |
822 | 11 | sfread(Buffer, 1, 32, arc4_stream->s); |
823 | | |
824 | 11 | pdfi_close_file(ctx, arc4_stream); |
825 | 11 | pdfi_close_memory_stream(ctx, NULL, stream); |
826 | 11 | } |
827 | | |
828 | | /* Algorithm 3.7, step 3, the result of step 2 purports to be the user password, check it */ |
829 | 43 | code = check_user_password_preR5(ctx, Buffer, 32, KeyLen, R); |
830 | | |
831 | 43 | error: |
832 | 43 | pdfi_countdown(EKey); |
833 | 43 | return code; |
834 | 43 | } |
835 | | |
836 | | /* Compute a decryption key for an 'object'. The decryption key for a string or stream is |
837 | | * calculated by algorithm 3.1. |
838 | | */ |
839 | | int pdfi_compute_objkey(pdf_context *ctx, pdf_obj *obj, pdf_string **Key) |
840 | 24.3k | { |
841 | 24.3k | char *Buffer; |
842 | 24.3k | int idx, ELength, code = 0, md5_length = 0; |
843 | 24.3k | gs_md5_state_t md5; |
844 | 24.3k | int64_t object_num; |
845 | 24.3k | uint32_t generation_num; |
846 | | |
847 | 24.3k | if (ctx->encryption.R < 5) { |
848 | 21.4k | if (obj->object_num == 0) { |
849 | | /* The object is a direct object, use the object number of the container instead */ |
850 | 13.1k | object_num = obj->indirect_num; |
851 | 13.1k | generation_num = obj->indirect_gen; |
852 | 13.1k | } else { |
853 | 8.24k | object_num = obj->object_num; |
854 | 8.24k | generation_num = obj->generation_num; |
855 | 8.24k | } |
856 | | |
857 | | /* Step 1, obtain the object and generation numbers (see arguments). If the string is |
858 | | * a direct object, use the identifier of the indirect object containing it. |
859 | | * Buffer length is a maximum of the Encryption key + 3 bytes from the object number |
860 | | * + 2 bytes from the generation number and (for AES filters) 4 bytes of sALT. |
861 | | * But... We must make sure the buffer is large enough for the 128 bits of an MD5 hash. |
862 | | */ |
863 | 21.4k | md5_length = ctx->encryption.EKey->length + 9; |
864 | 21.4k | if (md5_length < 16) |
865 | 4.52k | md5_length = 16; |
866 | | |
867 | 21.4k | Buffer = (char *)gs_alloc_bytes(ctx->memory, md5_length, ""); |
868 | 21.4k | if (Buffer == NULL) |
869 | 0 | return gs_note_error(gs_error_VMerror); |
870 | | |
871 | | /* Step 2, Treating the object number and generation number as binary integers, extend |
872 | | * the original n-byte encryption key (calculated in pdfi_read_Encryption) to n+5 bytes |
873 | | * by appending the low order 3 bytes of the object number and the low order 2 bytes of |
874 | | * the generation number in that order, low-order byte first. (n is 5 unless the value |
875 | | * of V in the encryption dictionary is greater than 1 in which case n is the value of |
876 | | * Length divided by 8). Because we store the encryption key is as a PDF string object, |
877 | | * we can just use the length of the string data, we calculated the length as part of |
878 | | * creating the key. |
879 | | */ |
880 | 21.4k | memcpy(Buffer, ctx->encryption.EKey->data, ctx->encryption.EKey->length); |
881 | 21.4k | idx = ctx->encryption.EKey->length; |
882 | 21.4k | Buffer[idx] = object_num & 0xff; |
883 | 21.4k | Buffer[++idx] = (object_num & 0xff00) >> 8; |
884 | 21.4k | Buffer[++idx] = (object_num & 0xff0000) >> 16; |
885 | 21.4k | Buffer[++idx] = generation_num & 0xff; |
886 | 21.4k | Buffer[++idx] = (generation_num & 0xff00) >> 8; |
887 | | |
888 | 21.4k | md5_length = ctx->encryption.EKey->length + 5; |
889 | | |
890 | | /* If using the AES algorithm, extend the encryption key an additional 4 bytes |
891 | | * by adding the value "sAlT" which corresponds to the hexadecimal 0x73416c54 |
892 | | * (This addition is done for backward compatibility and is not intended to |
893 | | * provide addtional security). |
894 | | */ |
895 | 21.4k | if (ctx->encryption.StmF == CRYPT_AESV2 || ctx->encryption.StmF == CRYPT_AESV3){ |
896 | 16.6k | memcpy(&Buffer[++idx], sAlTString, 4); |
897 | 16.6k | md5_length += 4; |
898 | 16.6k | } |
899 | | |
900 | | /* Step 3 |
901 | | * Initialise the MD5 function and pass the result of step 2 as input to this function |
902 | | */ |
903 | 21.4k | gs_md5_init(&md5); |
904 | 21.4k | gs_md5_append(&md5, (gs_md5_byte_t *)Buffer, md5_length); |
905 | 21.4k | gs_md5_finish(&md5, (gs_md5_byte_t *)Buffer); |
906 | | |
907 | | /* Step 4 |
908 | | * Use the first n+5 bytes, up to a maximum of 16, of the output from the MD5 |
909 | | * hash as the key for the RC4 or AES symmetric key algorithms, along with the |
910 | | * string or stream data to be encrypted. |
911 | | */ |
912 | 21.4k | ELength = ctx->encryption.EKey->length + 5; |
913 | 21.4k | if (ELength > 16) |
914 | 16.9k | ELength = 16; |
915 | | |
916 | 21.4k | code = pdfi_object_alloc(ctx, PDF_STRING, (uint64_t)ELength, (pdf_obj **)Key); |
917 | 21.4k | if (code >= 0) |
918 | 21.4k | memcpy((*Key)->data, Buffer, ELength); |
919 | | /* pdfi_object_alloc() creates objects with a refrence count of 0 */ |
920 | 21.4k | pdfi_countup(*Key); |
921 | | |
922 | 21.4k | gs_free_object(ctx->memory, Buffer, ""); |
923 | 21.4k | } else { |
924 | | /* Revision 5 & 6 don't use the object number and generation, just return the pre-calculated key */ |
925 | 2.93k | *Key = ctx->encryption.EKey; |
926 | 2.93k | pdfi_countup(*Key); |
927 | 2.93k | } |
928 | 24.3k | return code; |
929 | 24.3k | } |
930 | | |
931 | | int pdfi_decrypt_string(pdf_context *ctx, pdf_string *string) |
932 | 15.5k | { |
933 | 15.5k | int code = 0, bytes_decrypted = 0; |
934 | 15.5k | pdf_c_stream *stream = NULL, *crypt_stream = NULL; |
935 | 15.5k | pdf_string *EKey = NULL; |
936 | 15.5k | char *Buffer = NULL; |
937 | | |
938 | 15.5k | if (ctx->encryption.StrF == CRYPT_IDENTITY) |
939 | 0 | return 0; |
940 | | |
941 | 15.5k | if (!is_compressed_object(ctx, string->indirect_num, string->indirect_gen)) { |
942 | 15.5k | Buffer = (char *)gs_alloc_bytes(ctx->memory, string->length, "pdfi_decrypt_string"); |
943 | 15.5k | if (Buffer == NULL) |
944 | 0 | return_error(gs_error_VMerror); |
945 | | |
946 | 15.5k | code = pdfi_compute_objkey(ctx, (pdf_obj *)string, &EKey); |
947 | 15.5k | if (code < 0) |
948 | 0 | goto error; |
949 | | |
950 | 15.5k | code = pdfi_open_memory_stream_from_memory(ctx, string->length, (byte *)string->data, &stream, true); |
951 | 15.5k | if (code < 0) |
952 | 0 | goto error; |
953 | | |
954 | 15.5k | switch(ctx->encryption.StrF) { |
955 | | /* There are only two possible filters, RC4 or AES, we take care |
956 | | * of the number of bits in the key by using ctx->Length. |
957 | | */ |
958 | 0 | case CRYPT_IDENTITY: |
959 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
960 | 0 | code = 0; |
961 | 0 | goto error; |
962 | 0 | break; |
963 | 3.08k | case CRYPT_V1: |
964 | 3.31k | case CRYPT_V2: |
965 | 3.31k | code = pdfi_apply_Arc4_filter(ctx, EKey, stream, &crypt_stream); |
966 | 3.31k | break; |
967 | 9.82k | case CRYPT_AESV2: |
968 | 12.1k | case CRYPT_AESV3: |
969 | 12.1k | code = pdfi_apply_AES_filter(ctx, EKey, 1, stream, &crypt_stream); |
970 | 12.1k | break; |
971 | 0 | default: |
972 | 0 | code = gs_error_rangecheck; |
973 | 15.5k | } |
974 | 15.5k | if (code < 0) { |
975 | 0 | pdfi_close_memory_stream(ctx, NULL, stream); |
976 | 0 | goto error; |
977 | 0 | } |
978 | | |
979 | | /* The decrypted string length will likely be less than the original encrypted |
980 | | * string length. sfread won't tell us how many bytes it actually read, so we need |
981 | | * to decrypt one byte at a time until it returns EOD/ERRC. Then we can copy the |
982 | | * bytes we actually read and change the string length. |
983 | | */ |
984 | 1.16M | for (bytes_decrypted = 0;bytes_decrypted < string->length;bytes_decrypted++) { |
985 | 1.16M | code = sfread(&Buffer[bytes_decrypted], 1, 1, crypt_stream->s); |
986 | 1.16M | if (code != 1) { |
987 | 12.1k | code = 0; |
988 | 12.1k | break; |
989 | 12.1k | } |
990 | 1.16M | } |
991 | | |
992 | 15.5k | pdfi_close_file(ctx, crypt_stream); |
993 | 15.5k | pdfi_close_memory_stream(ctx, NULL, stream); |
994 | | |
995 | 15.5k | string->length = bytes_decrypted; |
996 | 15.5k | memcpy(string->data, Buffer, string->length); |
997 | 15.5k | } |
998 | | |
999 | 15.5k | error: |
1000 | 15.5k | gs_free_object(ctx->memory, Buffer, "pdfi_decrypt_string"); |
1001 | 15.5k | pdfi_countdown(EKey); |
1002 | 15.5k | return code; |
1003 | 15.5k | } |
1004 | | |
1005 | | /* Read the Encrypt dictionary entries and store the relevant ones |
1006 | | * in the PDF context for easy access. Return < 0 = error, 0 = encrypted |
1007 | | * and read the encryption details, 1 = not encrypted. |
1008 | | */ |
1009 | | static int pdfi_read_Encrypt_dict(pdf_context *ctx, int *KeyLen) |
1010 | 1.19k | { |
1011 | 1.19k | int code = 0; |
1012 | 1.19k | pdf_dict *CF_dict = NULL, *StdCF_dict = NULL; |
1013 | 1.19k | pdf_dict *d = NULL, *d1 = NULL; |
1014 | 1.19k | pdf_obj *o = NULL; |
1015 | 1.19k | bool b; |
1016 | 1.19k | pdf_string *s = NULL; |
1017 | 1.19k | int64_t i64; |
1018 | 1.19k | double f; |
1019 | | |
1020 | 1.19k | if (ctx->args.pdfdebug) |
1021 | 0 | outprintf(ctx->memory, "%% Checking for Encrypt dictionary\n"); |
1022 | | |
1023 | | /* See comment in pdfi_read_Root() for details of why we indirect through 'd' */ |
1024 | 1.19k | d1 = ctx->Trailer; |
1025 | 1.19k | pdfi_countup(d1); |
1026 | 1.19k | code = pdfi_dict_get(ctx, d1, "Encrypt", (pdf_obj **)&d); |
1027 | 1.19k | pdfi_countdown(d1); |
1028 | 1.19k | d1 = NULL; |
1029 | | |
1030 | | /* Undefined is acceptable here, it just means the PDF file is not ostensibly encrypted */ |
1031 | | /* NB pdfi_process_pdf_file() always checks for the Encrypt dictionary before we |
1032 | | * get here, so there shouldn't be a problem..... |
1033 | | */ |
1034 | 1.19k | if (code == gs_error_undefined) |
1035 | 0 | return 1; |
1036 | 1.19k | else |
1037 | 1.19k | if (code < 0) |
1038 | 0 | goto done; |
1039 | | |
1040 | 1.19k | code = pdfi_dict_get_type(ctx, d, "Filter", PDF_NAME, &o); |
1041 | 1.19k | if (code < 0) |
1042 | 12 | goto done; |
1043 | | |
1044 | 1.18k | if (!pdfi_name_is((pdf_name *)o, "Standard")) { |
1045 | 4 | char *Str = NULL; |
1046 | | |
1047 | 4 | Str = (char *)gs_alloc_bytes(ctx->memory, ((pdf_name *)o)->length + 1, "temp string for warning"); |
1048 | 4 | if (Str == NULL) { |
1049 | 0 | code = gs_note_error(gs_error_VMerror); |
1050 | 0 | goto done; |
1051 | 0 | } |
1052 | 4 | memset(Str, 0x00, ((pdf_name *)o)->length + 1); |
1053 | 4 | memcpy(Str, ((pdf_name *)o)->data, ((pdf_name *)o)->length); |
1054 | 4 | emprintf1(ctx->memory, "\n **** Warning: This file uses an unknown security handler %s\n", Str); |
1055 | 4 | gs_free_object(ctx->memory, Str, "temp string for warning"); |
1056 | 4 | code = gs_note_error(gs_error_typecheck); |
1057 | 4 | goto done; |
1058 | 4 | } |
1059 | 1.18k | pdfi_countdown(o); |
1060 | 1.18k | o = NULL; |
1061 | | |
1062 | 1.18k | *KeyLen = 0; |
1063 | 1.18k | ctx->encryption.V = -1; |
1064 | | |
1065 | 1.18k | code = pdfi_dict_get_int(ctx, d, "R", &i64); |
1066 | 1.18k | if (code < 0) |
1067 | 1 | goto done; |
1068 | 1.18k | ctx->encryption.R = (int)i64; |
1069 | | |
1070 | | /* V is required for PDF 2.0 but only strongly recommended for earlier versions */ |
1071 | 1.18k | code = pdfi_dict_known(ctx, d, "V", &b); |
1072 | 1.18k | if (code < 0) |
1073 | 0 | goto done; |
1074 | | |
1075 | 1.18k | if (b) { |
1076 | 1.18k | code = pdfi_dict_get_int(ctx, d, "V", &i64); |
1077 | 1.18k | if (code < 0) |
1078 | 0 | goto done; |
1079 | | |
1080 | 1.18k | if (i64 < 1 || i64 > 5) { |
1081 | 3 | code = gs_error_rangecheck; |
1082 | 3 | goto done; |
1083 | 3 | } |
1084 | | |
1085 | 1.17k | ctx->encryption.V = (int)i64; |
1086 | | |
1087 | 1.17k | code = pdfi_dict_knownget_number(ctx, d, "Length", &f); |
1088 | 1.17k | if (code < 0) |
1089 | 0 | goto done; |
1090 | | |
1091 | 1.17k | if (code > 0) |
1092 | 1.13k | *KeyLen = (int)f; |
1093 | 1.17k | } |
1094 | | |
1095 | 1.17k | code = pdfi_dict_get_int(ctx, d, "P", &i64); |
1096 | 1.17k | if (code < 0) |
1097 | 0 | goto done; |
1098 | 1.17k | ctx->encryption.P = (int)i64; |
1099 | | |
1100 | 1.17k | code = pdfi_dict_get_type(ctx, d, "O", PDF_STRING, (pdf_obj **)&s); |
1101 | 1.17k | if (code < 0) |
1102 | 0 | goto done; |
1103 | | |
1104 | 1.17k | if (ctx->encryption.R < 5) { |
1105 | 732 | if (s->length < 32) { |
1106 | 12 | code = gs_note_error(gs_error_rangecheck); |
1107 | 12 | goto done; |
1108 | 12 | } |
1109 | 720 | memcpy(ctx->encryption.O, s->data, 32); |
1110 | 720 | } else { |
1111 | 446 | if (s->length < 48) { |
1112 | 5 | code = gs_note_error(gs_error_rangecheck); |
1113 | 5 | goto done; |
1114 | 5 | } |
1115 | 441 | memcpy(ctx->encryption.O, s->data, 48); |
1116 | 441 | } |
1117 | 1.16k | pdfi_countdown(s); |
1118 | 1.16k | s = NULL; |
1119 | | |
1120 | 1.16k | code = pdfi_dict_get_type(ctx, d, "U", PDF_STRING, (pdf_obj **)&s); |
1121 | 1.16k | if (code < 0) |
1122 | 0 | goto done; |
1123 | | |
1124 | 1.16k | if (ctx->encryption.R < 5) { |
1125 | 720 | if (s->length < 32) { |
1126 | 12 | code = gs_note_error(gs_error_rangecheck); |
1127 | 12 | goto done; |
1128 | 12 | } |
1129 | 708 | memcpy(ctx->encryption.U, s->data, 32); |
1130 | 708 | } else { |
1131 | 441 | if (s->length < 48) { |
1132 | 7 | code = gs_note_error(gs_error_rangecheck); |
1133 | 7 | goto done; |
1134 | 7 | } |
1135 | 434 | memcpy(ctx->encryption.U, s->data, 48); |
1136 | 434 | } |
1137 | 1.14k | pdfi_countdown(s); |
1138 | 1.14k | s = NULL; |
1139 | | |
1140 | 1.14k | code = pdfi_dict_knownget_bool(ctx, d, "EncryptMetadata", &b); |
1141 | 1.14k | if (code < 0) |
1142 | 0 | goto done; |
1143 | 1.14k | if (code > 0) { |
1144 | 86 | ctx->encryption.EncryptMetadata = b; |
1145 | 86 | code = 0; |
1146 | 86 | } |
1147 | 1.05k | else |
1148 | 1.05k | ctx->encryption.EncryptMetadata = true; |
1149 | | |
1150 | 1.14k | if (ctx->encryption.R > 3) { |
1151 | | /* Check the Encrypt dictionary has default values for Stmf and StrF |
1152 | | * and that they have the names /StdCF. We don't support anything else. |
1153 | | */ |
1154 | 881 | code = pdfi_dict_get_type(ctx, d, "StmF", PDF_NAME, &o); |
1155 | 881 | if (code < 0) |
1156 | 6 | goto done; |
1157 | 875 | if (!pdfi_name_is((pdf_name *)o, "StdCF")) { |
1158 | 4 | if (pdfi_name_is((pdf_name *)o, "Identity")) { |
1159 | 0 | ctx->encryption.StmF = CRYPT_IDENTITY; |
1160 | 4 | } else { |
1161 | 4 | code = gs_note_error(gs_error_undefined); |
1162 | 4 | goto done; |
1163 | 4 | } |
1164 | 4 | } |
1165 | 871 | pdfi_countdown(o); |
1166 | 871 | o = NULL; |
1167 | | |
1168 | 871 | code = pdfi_dict_knownget_type(ctx, d, "StrF", PDF_NAME, &o); |
1169 | 871 | if (code < 0) |
1170 | 0 | goto done; |
1171 | 871 | if (code == 0) { |
1172 | 11 | code = gs_note_error(gs_error_undefined); |
1173 | 11 | goto done; |
1174 | 11 | } |
1175 | 860 | if (!pdfi_name_is((pdf_name *)o, "StdCF")) { |
1176 | 19 | if (pdfi_name_is((pdf_name *)o, "Identity")) { |
1177 | 12 | ctx->encryption.StrF = CRYPT_IDENTITY; |
1178 | 12 | } else { |
1179 | 7 | code = gs_note_error(gs_error_undefined); |
1180 | 7 | goto done; |
1181 | 7 | } |
1182 | 19 | } |
1183 | 853 | pdfi_countdown(o); |
1184 | 853 | o = NULL; |
1185 | | |
1186 | | /* Validated StmF and StrF, now check the Encrypt dictionary for the definition of |
1187 | | * the Crypt Filter dictionary and ensure it has a /StdCF dictionary. |
1188 | | */ |
1189 | 853 | code = pdfi_dict_get_type(ctx, d, "CF", PDF_DICT, (pdf_obj **)&CF_dict); |
1190 | 853 | if (code < 0) |
1191 | 10 | goto done; |
1192 | | |
1193 | 843 | code = pdfi_dict_get_type(ctx, CF_dict, "StdCF", PDF_DICT, (pdf_obj **)&StdCF_dict); |
1194 | 843 | if (code < 0) |
1195 | 12 | goto done; |
1196 | | |
1197 | 831 | code = pdfi_dict_get_type(ctx, StdCF_dict, "CFM", PDF_NAME, &o); |
1198 | 831 | if (code < 0) |
1199 | 5 | goto done; |
1200 | | |
1201 | 826 | if (pdfi_name_is((pdf_name *)o, "V2")) { |
1202 | 2 | if (ctx->encryption.StmF == CRYPT_NONE) |
1203 | 2 | ctx->encryption.StmF = CRYPT_V2; |
1204 | 2 | if (ctx->encryption.StrF == CRYPT_NONE) |
1205 | 2 | ctx->encryption.StrF = CRYPT_V2; |
1206 | 824 | } else { |
1207 | 824 | if (pdfi_name_is((pdf_name *)o, "AESV2")) { |
1208 | 441 | if (ctx->encryption.StmF == CRYPT_NONE) |
1209 | 441 | ctx->encryption.StmF = CRYPT_AESV2; |
1210 | 441 | if (ctx->encryption.StrF == CRYPT_NONE) |
1211 | 429 | ctx->encryption.StrF = CRYPT_AESV2; |
1212 | 441 | } else { |
1213 | 383 | if (pdfi_name_is((pdf_name *)o, "AESV3")) { |
1214 | 376 | if (ctx->encryption.StmF == CRYPT_NONE) |
1215 | 376 | ctx->encryption.StmF = CRYPT_AESV3; |
1216 | 376 | if (ctx->encryption.StrF == CRYPT_NONE) |
1217 | 376 | ctx->encryption.StrF = CRYPT_AESV3; |
1218 | 376 | } else { |
1219 | 7 | emprintf(ctx->memory, "\n **** Error: Unknown default encryption method in crypt filter.\n"); |
1220 | 7 | code = gs_error_rangecheck; |
1221 | 7 | goto done; |
1222 | 7 | } |
1223 | 383 | } |
1224 | 824 | } |
1225 | 819 | pdfi_countdown(o); |
1226 | 819 | o = NULL; |
1227 | | |
1228 | 819 | if (ctx->encryption.R > 4) { |
1229 | 377 | code = pdfi_dict_get_type(ctx, d, "OE", PDF_STRING, (pdf_obj **)&s); |
1230 | 377 | if (code < 0) |
1231 | 4 | goto done; |
1232 | | |
1233 | 373 | if (s->length != 32) { |
1234 | 8 | code = gs_note_error(gs_error_rangecheck); |
1235 | 8 | goto done; |
1236 | 8 | } |
1237 | 365 | memcpy(ctx->encryption.OE, s->data, 32); |
1238 | 365 | pdfi_countdown(s); |
1239 | 365 | s = NULL; |
1240 | | |
1241 | 365 | code = pdfi_dict_get_type(ctx, d, "UE", PDF_STRING, (pdf_obj **)&s); |
1242 | 365 | if (code < 0) |
1243 | 0 | goto done; |
1244 | | |
1245 | 365 | if (s->length != 32) { |
1246 | 9 | code = gs_note_error(gs_error_rangecheck); |
1247 | 9 | goto done; |
1248 | 9 | } |
1249 | 356 | memcpy(ctx->encryption.UE, s->data, 32); |
1250 | 356 | pdfi_countdown(s); |
1251 | 356 | s = NULL; |
1252 | 356 | } |
1253 | 819 | } |
1254 | | |
1255 | 1.19k | done: |
1256 | 1.19k | pdfi_countdown(StdCF_dict); |
1257 | 1.19k | pdfi_countdown(CF_dict); |
1258 | 1.19k | pdfi_countdown(s); |
1259 | 1.19k | pdfi_countdown(o); |
1260 | 1.19k | pdfi_countdown(d); |
1261 | 1.19k | return code; |
1262 | 1.14k | } |
1263 | | |
1264 | | static int check_password_preR5(pdf_context *ctx, char *Password, int PasswordLen, int KeyLen, int Revision) |
1265 | 703 | { |
1266 | 703 | int code; |
1267 | | |
1268 | 703 | if (PasswordLen != 0) { |
1269 | 0 | code = check_user_password_preR5(ctx, Password, PasswordLen, KeyLen, Revision); |
1270 | 0 | if (code >= 0) |
1271 | 0 | return 0; |
1272 | | |
1273 | 0 | code = check_owner_password_preR5(ctx, Password, PasswordLen, KeyLen, Revision); |
1274 | 0 | if (code >= 0) |
1275 | 0 | return 0; |
1276 | 0 | } |
1277 | 703 | code = check_user_password_preR5(ctx, (char *)"", 0, KeyLen, Revision); |
1278 | 703 | if (code >= 0) |
1279 | 660 | return 0; |
1280 | | |
1281 | 43 | return check_owner_password_preR5(ctx, (char *)"", 0, KeyLen, Revision); |
1282 | 703 | } |
1283 | | |
1284 | | static int check_password_R5(pdf_context *ctx, char *Password, int PasswordLen, int KeyLen) |
1285 | 0 | { |
1286 | 0 | int code; |
1287 | |
|
1288 | 0 | if (PasswordLen != 0) { |
1289 | 0 | pdf_string *P = NULL, *P_UTF8 = NULL; |
1290 | |
|
1291 | 0 | code = check_user_password_R5(ctx, Password, PasswordLen, KeyLen); |
1292 | 0 | if (code >= 0) |
1293 | 0 | return 0; |
1294 | | |
1295 | 0 | code = check_owner_password_R5(ctx, Password, PasswordLen, KeyLen); |
1296 | 0 | if (code >= 0) |
1297 | 0 | return 0; |
1298 | | |
1299 | | /* If the supplied Password fails as the user *and* owner password, maybe its in |
1300 | | * the locale, not UTF-8, try converting to UTF-8 |
1301 | | */ |
1302 | 0 | code = pdfi_object_alloc(ctx, PDF_STRING, PasswordLen, (pdf_obj **)&P); |
1303 | 0 | if (code < 0) |
1304 | 0 | return code; |
1305 | 0 | memcpy(P->data, Password, PasswordLen); |
1306 | 0 | pdfi_countup(P); |
1307 | 0 | code = locale_to_utf8(ctx, P, &P_UTF8); |
1308 | 0 | if (code < 0) { |
1309 | 0 | pdfi_countdown(P); |
1310 | 0 | return code; |
1311 | 0 | } |
1312 | 0 | code = check_user_password_R5(ctx, (char *)P_UTF8->data, P_UTF8->length, KeyLen); |
1313 | 0 | if (code >= 0) { |
1314 | 0 | pdfi_countdown(P); |
1315 | 0 | pdfi_countdown(P_UTF8); |
1316 | 0 | return code; |
1317 | 0 | } |
1318 | | |
1319 | 0 | code = check_owner_password_R5(ctx, (char *)P_UTF8->data, P_UTF8->length, KeyLen); |
1320 | 0 | pdfi_countdown(P); |
1321 | 0 | pdfi_countdown(P_UTF8); |
1322 | 0 | if (code >= 0) |
1323 | 0 | return code; |
1324 | 0 | } |
1325 | 0 | code = check_user_password_R5(ctx, (char *)"", 0, KeyLen); |
1326 | 0 | if (code >= 0) |
1327 | 0 | return 0; |
1328 | | |
1329 | 0 | return check_owner_password_R5(ctx, (char *)"", 0, KeyLen); |
1330 | 0 | } |
1331 | | |
1332 | | static int check_password_R6(pdf_context *ctx, char *Password, int PasswordLen, int KeyLen) |
1333 | 356 | { |
1334 | 356 | int code; |
1335 | | |
1336 | 356 | if (PasswordLen != 0) { |
1337 | 0 | pdf_string *P = NULL, *P_UTF8 = NULL; |
1338 | |
|
1339 | 0 | code = check_user_password_R6(ctx, Password, PasswordLen, KeyLen); |
1340 | 0 | if (code >= 0) |
1341 | 0 | return 0; |
1342 | | |
1343 | 0 | code = check_owner_password_R6(ctx, Password, PasswordLen, KeyLen); |
1344 | 0 | if (code >= 0) |
1345 | 0 | return 0; |
1346 | | /* If the supplied Password fails as the user *and* owner password, maybe its in |
1347 | | * the locale, not UTF-8, try converting to UTF-8 |
1348 | | */ |
1349 | 0 | code = pdfi_object_alloc(ctx, PDF_STRING, PasswordLen, (pdf_obj **)&P); |
1350 | 0 | if (code < 0) |
1351 | 0 | return code; |
1352 | 0 | memcpy(P->data, Password, PasswordLen); |
1353 | 0 | pdfi_countup(P); |
1354 | 0 | code = locale_to_utf8(ctx, P, &P_UTF8); |
1355 | 0 | if (code < 0) { |
1356 | 0 | pdfi_countdown(P); |
1357 | 0 | return code; |
1358 | 0 | } |
1359 | 0 | code = check_user_password_R5(ctx, (char *)P_UTF8->data, P_UTF8->length, KeyLen); |
1360 | 0 | if (code >= 0) { |
1361 | 0 | pdfi_countdown(P); |
1362 | 0 | pdfi_countdown(P_UTF8); |
1363 | 0 | return code; |
1364 | 0 | } |
1365 | | |
1366 | 0 | code = check_owner_password_R5(ctx, (char *)P_UTF8->data, P_UTF8->length, KeyLen); |
1367 | 0 | pdfi_countdown(P); |
1368 | 0 | pdfi_countdown(P_UTF8); |
1369 | 0 | if (code >= 0) |
1370 | 0 | return code; |
1371 | 0 | } |
1372 | 356 | code = check_user_password_R6(ctx, (char *)"", 0, KeyLen); |
1373 | 356 | if (code >= 0) |
1374 | 177 | return 0; |
1375 | | |
1376 | 179 | return check_owner_password_R6(ctx, (char *)"", 0, KeyLen); |
1377 | 356 | } |
1378 | | |
1379 | | /* Read the Encrypt dictionary entries and store the relevant ones |
1380 | | * in the PDF context for easy access. Check whether the file is |
1381 | | * readable without a password and if not, check to see if we've been |
1382 | | * supplied a password. If we have try the password as the user password |
1383 | | * and if that fails as the owner password. Store the calculated decryption key |
1384 | | * for later use decrypting objects. |
1385 | | */ |
1386 | | int pdfi_initialise_Decryption(pdf_context *ctx) |
1387 | 1.19k | { |
1388 | 1.19k | int code = 0, KeyLen = 0; |
1389 | | |
1390 | 1.19k | code = pdfi_read_Encrypt_dict(ctx, &KeyLen); |
1391 | 1.19k | if (code > 0) |
1392 | 0 | return 0; |
1393 | 1.19k | if (code < 0) |
1394 | 139 | return code; |
1395 | | |
1396 | 1.05k | switch(ctx->encryption.R) { |
1397 | 231 | case 2: |
1398 | | /* Set up the defaults if not already set */ |
1399 | | /* R of 2 means V < 2 which is either algorithm 3.1 with a 40-bit key |
1400 | | * or an undocumented and unsupported algorithm. |
1401 | | */ |
1402 | 231 | if (ctx->encryption.V >= 0) { |
1403 | 231 | if (ctx->encryption.V == 0) { |
1404 | 0 | code = gs_note_error(gs_error_undefined); |
1405 | 0 | goto done; |
1406 | 0 | } |
1407 | 231 | } |
1408 | | /* Revision 2 is always 40-bit RC4 */ |
1409 | 231 | if (KeyLen != 0 && KeyLen != 40) |
1410 | 2 | if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_undefined), NULL, E_PDF_INVALID_DECRYPT_LEN, "pdfi_initialise_Decryption", NULL)) < 0) |
1411 | 0 | goto done; |
1412 | 231 | KeyLen = 40; |
1413 | 231 | if (ctx->encryption.StmF == CRYPT_NONE) |
1414 | 231 | ctx->encryption.StmF = CRYPT_V1; |
1415 | 231 | if (ctx->encryption.StrF == CRYPT_NONE) |
1416 | 231 | ctx->encryption.StrF = CRYPT_V1; |
1417 | 231 | code = check_password_preR5(ctx, ctx->encryption.Password, ctx->encryption.PasswordLen, KeyLen, 2); |
1418 | 231 | break; |
1419 | 30 | case 3: |
1420 | | /* Set up the defaults if not already set */ |
1421 | 30 | if (ctx->encryption.V >= 0) { |
1422 | 30 | if (ctx->encryption.V == 3) { |
1423 | 0 | code = gs_note_error(gs_error_undefined); |
1424 | 0 | goto done; |
1425 | 0 | } |
1426 | 30 | } |
1427 | | /* Revision 3 *may* be more than 40 bits of RC4 */ |
1428 | 30 | if (KeyLen != 0) { |
1429 | 24 | if (KeyLen < 40 || KeyLen > 128 || KeyLen % 8 != 0) { |
1430 | 2 | pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_DECRYPT_LEN, "pdfi_initialise_Decryption", NULL); |
1431 | 2 | KeyLen = 128; |
1432 | 2 | } |
1433 | 24 | } else |
1434 | 6 | KeyLen = 40; |
1435 | 30 | if (ctx->encryption.StmF == CRYPT_NONE) |
1436 | 30 | ctx->encryption.StmF = CRYPT_V2; |
1437 | 30 | if (ctx->encryption.StrF == CRYPT_NONE) |
1438 | 30 | ctx->encryption.StrF = CRYPT_V2; |
1439 | 30 | code = check_password_preR5(ctx, ctx->encryption.Password, ctx->encryption.PasswordLen, KeyLen, 3); |
1440 | 30 | break; |
1441 | 442 | case 4: |
1442 | 442 | if (ctx->encryption.StrF != CRYPT_IDENTITY || ctx->encryption.StmF != CRYPT_IDENTITY) { |
1443 | | /* Revision 4 is either AES or RC4, but its always 128-bits */ |
1444 | 442 | if (KeyLen != 0) |
1445 | 442 | pdfi_set_warning(ctx, 0, NULL, W_PDF_SPURIOUS_DECRYPT_LEN, "pdfi_initialise_Decryption", NULL); |
1446 | 442 | KeyLen = 128; |
1447 | | /* We can't set the encryption filter, so we have to hope the PDF file did */ |
1448 | 442 | code = check_password_preR5(ctx, ctx->encryption.Password, ctx->encryption.PasswordLen, KeyLen, 4); |
1449 | 442 | } |
1450 | 442 | break; |
1451 | 0 | case 5: |
1452 | | /* Set up the defaults if not already set */ |
1453 | 0 | if (KeyLen != 0) |
1454 | 0 | pdfi_set_warning(ctx, 0, NULL, W_PDF_SPURIOUS_DECRYPT_LEN, "pdfi_initialise_Decryption", NULL); |
1455 | 0 | KeyLen = 256; |
1456 | 0 | if (ctx->encryption.StmF == CRYPT_NONE) |
1457 | 0 | ctx->encryption.StmF = CRYPT_AESV2; |
1458 | 0 | if (ctx->encryption.StrF == CRYPT_NONE) |
1459 | 0 | ctx->encryption.StrF = CRYPT_AESV2; |
1460 | 0 | code = check_password_R5(ctx, ctx->encryption.Password, ctx->encryption.PasswordLen, KeyLen); |
1461 | 0 | break; |
1462 | 356 | case 6: |
1463 | | /* Set up the defaults if not already set */ |
1464 | | /* Revision 6 is always 256-bit AES */ |
1465 | 356 | if (KeyLen != 0) |
1466 | 344 | pdfi_set_warning(ctx, 0, NULL, W_PDF_SPURIOUS_DECRYPT_LEN, "pdfi_initialise_Decryption", NULL); |
1467 | 356 | KeyLen = 256; |
1468 | 356 | if (ctx->encryption.StmF == CRYPT_NONE) |
1469 | 0 | ctx->encryption.StmF = CRYPT_AESV3; |
1470 | 356 | if (ctx->encryption.StrF == CRYPT_NONE) |
1471 | 0 | ctx->encryption.StrF = CRYPT_AESV3; |
1472 | 356 | code = check_password_R6(ctx, ctx->encryption.Password, ctx->encryption.PasswordLen, KeyLen); |
1473 | 356 | break; |
1474 | 0 | default: |
1475 | 0 | emprintf1(ctx->memory, "\n **** Warning: This file uses an unknown standard security handler revision: %d\n", ctx->encryption.R); |
1476 | 0 | code = gs_error_rangecheck; |
1477 | 0 | goto done; |
1478 | 1.05k | } |
1479 | 1.05k | if (code < 0) { |
1480 | 119 | if(ctx->encryption.Password) { |
1481 | 0 | emprintf(ctx->memory, "\n **** Error: Password did not work.\n"); |
1482 | 0 | emprintf(ctx->memory, " Cannot decrypt PDF file.\n"); |
1483 | 0 | } else |
1484 | 119 | emprintf(ctx->memory, "\n **** This file requires a password for access.\n"); |
1485 | 119 | } else |
1486 | 940 | ctx->encryption.is_encrypted = true; |
1487 | | |
1488 | 1.05k | done: |
1489 | 1.05k | return code; |
1490 | 1.05k | } |