| 1 | #include "mupdf/fitz.h" | 
|---|
| 2 | #include "mupdf/pdf.h" | 
|---|
| 3 |  | 
|---|
| 4 | #include <string.h> | 
|---|
| 5 |  | 
|---|
| 6 | enum | 
|---|
| 7 | { | 
|---|
| 8 | PDF_CRYPT_NONE, | 
|---|
| 9 | PDF_CRYPT_RC4, | 
|---|
| 10 | PDF_CRYPT_AESV2, | 
|---|
| 11 | PDF_CRYPT_AESV3, | 
|---|
| 12 | PDF_CRYPT_UNKNOWN, | 
|---|
| 13 | }; | 
|---|
| 14 |  | 
|---|
| 15 | typedef struct pdf_crypt_filter_s pdf_crypt_filter; | 
|---|
| 16 |  | 
|---|
| 17 | struct pdf_crypt_filter_s | 
|---|
| 18 | { | 
|---|
| 19 | int method; | 
|---|
| 20 | int length; | 
|---|
| 21 | }; | 
|---|
| 22 |  | 
|---|
| 23 | struct pdf_crypt_s | 
|---|
| 24 | { | 
|---|
| 25 | pdf_obj *id; | 
|---|
| 26 |  | 
|---|
| 27 | int v; | 
|---|
| 28 | int length; | 
|---|
| 29 | pdf_obj *cf; | 
|---|
| 30 | pdf_crypt_filter stmf; | 
|---|
| 31 | pdf_crypt_filter strf; | 
|---|
| 32 |  | 
|---|
| 33 | int r; | 
|---|
| 34 | unsigned char o[48]; | 
|---|
| 35 | unsigned char u[48]; | 
|---|
| 36 | unsigned char oe[32]; | 
|---|
| 37 | unsigned char ue[32]; | 
|---|
| 38 | unsigned char perms[16]; | 
|---|
| 39 | int p; | 
|---|
| 40 | int encrypt_metadata; | 
|---|
| 41 |  | 
|---|
| 42 | unsigned char key[32]; /* decryption key generated from password */ | 
|---|
| 43 | }; | 
|---|
| 44 |  | 
|---|
| 45 | static void pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, pdf_crypt *crypt, pdf_obj *name); | 
|---|
| 46 |  | 
|---|
| 47 | /* | 
|---|
| 48 | * Create crypt object for decrypting strings and streams | 
|---|
| 49 | * given the Encryption and ID objects. | 
|---|
| 50 | */ | 
|---|
| 51 |  | 
|---|
| 52 | pdf_crypt * | 
|---|
| 53 | pdf_new_crypt(fz_context *ctx, pdf_obj *dict, pdf_obj *id) | 
|---|
| 54 | { | 
|---|
| 55 | pdf_crypt *crypt; | 
|---|
| 56 | pdf_obj *obj; | 
|---|
| 57 |  | 
|---|
| 58 | crypt = fz_malloc_struct(ctx, pdf_crypt); | 
|---|
| 59 |  | 
|---|
| 60 | /* Common to all security handlers (PDF 1.7 table 3.18) */ | 
|---|
| 61 |  | 
|---|
| 62 | obj = pdf_dict_get(ctx, dict, PDF_NAME(Filter)); | 
|---|
| 63 | if (!pdf_is_name(ctx, obj)) | 
|---|
| 64 | { | 
|---|
| 65 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 66 | fz_throw(ctx, FZ_ERROR_GENERIC, "unspecified encryption handler"); | 
|---|
| 67 | } | 
|---|
| 68 | if (!pdf_name_eq(ctx, PDF_NAME(Standard), obj)) | 
|---|
| 69 | { | 
|---|
| 70 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 71 | fz_throw(ctx, FZ_ERROR_GENERIC, "unknown encryption handler: '%s'", pdf_to_name(ctx, obj)); | 
|---|
| 72 | } | 
|---|
| 73 |  | 
|---|
| 74 | crypt->v = 0; | 
|---|
| 75 | obj = pdf_dict_get(ctx, dict, PDF_NAME(V)); | 
|---|
| 76 | if (pdf_is_int(ctx, obj)) | 
|---|
| 77 | crypt->v = pdf_to_int(ctx, obj); | 
|---|
| 78 | if (crypt->v != 0 && crypt->v != 1 && crypt->v != 2 && crypt->v != 4 && crypt->v != 5) | 
|---|
| 79 | { | 
|---|
| 80 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 81 | fz_throw(ctx, FZ_ERROR_GENERIC, "unknown encryption version"); | 
|---|
| 82 | } | 
|---|
| 83 |  | 
|---|
| 84 | /* Standard security handler (PDF 1.7 table 3.19) */ | 
|---|
| 85 |  | 
|---|
| 86 | obj = pdf_dict_get(ctx, dict, PDF_NAME(R)); | 
|---|
| 87 | if (pdf_is_int(ctx, obj)) | 
|---|
| 88 | crypt->r = pdf_to_int(ctx, obj); | 
|---|
| 89 | else if (crypt->v <= 4) | 
|---|
| 90 | { | 
|---|
| 91 | fz_warn(ctx, "encryption dictionary missing revision value, guessing..."); | 
|---|
| 92 | if (crypt->v < 2) | 
|---|
| 93 | crypt->r = 2; | 
|---|
| 94 | else if (crypt->v == 2) | 
|---|
| 95 | crypt->r = 3; | 
|---|
| 96 | else if (crypt->v == 4) | 
|---|
| 97 | crypt->r = 4; | 
|---|
| 98 | } | 
|---|
| 99 | else | 
|---|
| 100 | { | 
|---|
| 101 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 102 | fz_throw(ctx, FZ_ERROR_GENERIC, "encryption dictionary missing version and revision value"); | 
|---|
| 103 | } | 
|---|
| 104 | if (crypt->r < 1 || crypt->r > 6) | 
|---|
| 105 | { | 
|---|
| 106 | int r = crypt->r; | 
|---|
| 107 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 108 | fz_throw(ctx, FZ_ERROR_GENERIC, "unknown crypt revision %d", r); | 
|---|
| 109 | } | 
|---|
| 110 |  | 
|---|
| 111 | obj = pdf_dict_get(ctx, dict, PDF_NAME(O)); | 
|---|
| 112 | if (pdf_is_string(ctx, obj) && pdf_to_str_len(ctx, obj) == 32) | 
|---|
| 113 | memcpy(crypt->o, pdf_to_str_buf(ctx, obj), 32); | 
|---|
| 114 | /* /O and /U are supposed to be 48 bytes long for revision 5 and 6, they're often longer, though */ | 
|---|
| 115 | else if (crypt->r >= 5 && pdf_is_string(ctx, obj) && pdf_to_str_len(ctx, obj) >= 48) | 
|---|
| 116 | memcpy(crypt->o, pdf_to_str_buf(ctx, obj), 48); | 
|---|
| 117 | else | 
|---|
| 118 | { | 
|---|
| 119 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 120 | fz_throw(ctx, FZ_ERROR_GENERIC, "encryption dictionary missing owner password"); | 
|---|
| 121 | } | 
|---|
| 122 |  | 
|---|
| 123 | obj = pdf_dict_get(ctx, dict, PDF_NAME(U)); | 
|---|
| 124 | if (pdf_is_string(ctx, obj) && pdf_to_str_len(ctx, obj) == 32) | 
|---|
| 125 | memcpy(crypt->u, pdf_to_str_buf(ctx, obj), 32); | 
|---|
| 126 | /* /O and /U are supposed to be 48 bytes long for revision 5 and 6, they're often longer, though */ | 
|---|
| 127 | else if (crypt->r >= 5 && pdf_is_string(ctx, obj) && pdf_to_str_len(ctx, obj) >= 48) | 
|---|
| 128 | memcpy(crypt->u, pdf_to_str_buf(ctx, obj), 48); | 
|---|
| 129 | else if (pdf_is_string(ctx, obj) && pdf_to_str_len(ctx, obj) < 32) | 
|---|
| 130 | { | 
|---|
| 131 | fz_warn(ctx, "encryption password key too short (%d)", pdf_to_str_len(ctx, obj)); | 
|---|
| 132 | memcpy(crypt->u, pdf_to_str_buf(ctx, obj), pdf_to_str_len(ctx, obj)); | 
|---|
| 133 | } | 
|---|
| 134 | else | 
|---|
| 135 | { | 
|---|
| 136 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 137 | fz_throw(ctx, FZ_ERROR_GENERIC, "encryption dictionary missing user password"); | 
|---|
| 138 | } | 
|---|
| 139 |  | 
|---|
| 140 | obj = pdf_dict_get(ctx, dict, PDF_NAME(P)); | 
|---|
| 141 | if (pdf_is_int(ctx, obj)) | 
|---|
| 142 | crypt->p = pdf_to_int(ctx, obj); | 
|---|
| 143 | else | 
|---|
| 144 | { | 
|---|
| 145 | fz_warn(ctx, "encryption dictionary missing permissions"); | 
|---|
| 146 | crypt->p = 0xfffffffc; | 
|---|
| 147 | } | 
|---|
| 148 |  | 
|---|
| 149 | if (crypt->r == 5 || crypt->r == 6) | 
|---|
| 150 | { | 
|---|
| 151 | obj = pdf_dict_get(ctx, dict, PDF_NAME(OE)); | 
|---|
| 152 | if (!pdf_is_string(ctx, obj) || pdf_to_str_len(ctx, obj) != 32) | 
|---|
| 153 | { | 
|---|
| 154 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 155 | fz_throw(ctx, FZ_ERROR_GENERIC, "encryption dictionary missing owner encryption key"); | 
|---|
| 156 | } | 
|---|
| 157 | memcpy(crypt->oe, pdf_to_str_buf(ctx, obj), 32); | 
|---|
| 158 |  | 
|---|
| 159 | obj = pdf_dict_get(ctx, dict, PDF_NAME(UE)); | 
|---|
| 160 | if (!pdf_is_string(ctx, obj) || pdf_to_str_len(ctx, obj) != 32) | 
|---|
| 161 | { | 
|---|
| 162 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 163 | fz_throw(ctx, FZ_ERROR_GENERIC, "encryption dictionary missing user encryption key"); | 
|---|
| 164 | } | 
|---|
| 165 | memcpy(crypt->ue, pdf_to_str_buf(ctx, obj), 32); | 
|---|
| 166 | } | 
|---|
| 167 |  | 
|---|
| 168 | crypt->encrypt_metadata = 1; | 
|---|
| 169 | obj = pdf_dict_get(ctx, dict, PDF_NAME(EncryptMetadata)); | 
|---|
| 170 | if (pdf_is_bool(ctx, obj)) | 
|---|
| 171 | crypt->encrypt_metadata = pdf_to_bool(ctx, obj); | 
|---|
| 172 |  | 
|---|
| 173 | /* Extract file identifier string */ | 
|---|
| 174 |  | 
|---|
| 175 | if (pdf_is_array(ctx, id) && pdf_array_len(ctx, id) == 2) | 
|---|
| 176 | { | 
|---|
| 177 | obj = pdf_array_get(ctx, id, 0); | 
|---|
| 178 | if (pdf_is_string(ctx, obj)) | 
|---|
| 179 | crypt->id = pdf_keep_obj(ctx, obj); | 
|---|
| 180 | } | 
|---|
| 181 | else | 
|---|
| 182 | fz_warn(ctx, "missing file identifier, may not be able to do decryption"); | 
|---|
| 183 |  | 
|---|
| 184 | /* Determine encryption key length */ | 
|---|
| 185 |  | 
|---|
| 186 | crypt->length = 40; | 
|---|
| 187 | if (crypt->v == 2 || crypt->v == 4) | 
|---|
| 188 | { | 
|---|
| 189 | obj = pdf_dict_get(ctx, dict, PDF_NAME(Length)); | 
|---|
| 190 | if (pdf_is_int(ctx, obj)) | 
|---|
| 191 | crypt->length = pdf_to_int(ctx, obj); | 
|---|
| 192 |  | 
|---|
| 193 | /* work-around for pdf generators that assume length is in bytes */ | 
|---|
| 194 | if (crypt->length < 40) | 
|---|
| 195 | crypt->length = crypt->length * 8; | 
|---|
| 196 |  | 
|---|
| 197 | if (crypt->length % 8 != 0) | 
|---|
| 198 | { | 
|---|
| 199 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 200 | fz_throw(ctx, FZ_ERROR_GENERIC, "invalid encryption key length"); | 
|---|
| 201 | } | 
|---|
| 202 | if (crypt->length < 40 || crypt->length > 128) | 
|---|
| 203 | { | 
|---|
| 204 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 205 | fz_throw(ctx, FZ_ERROR_GENERIC, "invalid encryption key length"); | 
|---|
| 206 | } | 
|---|
| 207 | } | 
|---|
| 208 |  | 
|---|
| 209 | if (crypt->v == 5) | 
|---|
| 210 | crypt->length = 256; | 
|---|
| 211 |  | 
|---|
| 212 | if (crypt->v == 0 || crypt->v == 1 || crypt->v == 2) | 
|---|
| 213 | { | 
|---|
| 214 | crypt->stmf.method = PDF_CRYPT_RC4; | 
|---|
| 215 | crypt->stmf.length = crypt->length; | 
|---|
| 216 |  | 
|---|
| 217 | crypt->strf.method = PDF_CRYPT_RC4; | 
|---|
| 218 | crypt->strf.length = crypt->length; | 
|---|
| 219 | } | 
|---|
| 220 |  | 
|---|
| 221 | if (crypt->v == 4 || crypt->v == 5) | 
|---|
| 222 | { | 
|---|
| 223 | crypt->stmf.method = PDF_CRYPT_NONE; | 
|---|
| 224 | crypt->stmf.length = crypt->length; | 
|---|
| 225 |  | 
|---|
| 226 | crypt->strf.method = PDF_CRYPT_NONE; | 
|---|
| 227 | crypt->strf.length = crypt->length; | 
|---|
| 228 |  | 
|---|
| 229 | obj = pdf_dict_get(ctx, dict, PDF_NAME(CF)); | 
|---|
| 230 | if (pdf_is_dict(ctx, obj)) | 
|---|
| 231 | { | 
|---|
| 232 | crypt->cf = pdf_keep_obj(ctx, obj); | 
|---|
| 233 | } | 
|---|
| 234 | else | 
|---|
| 235 | { | 
|---|
| 236 | crypt->cf = NULL; | 
|---|
| 237 | } | 
|---|
| 238 |  | 
|---|
| 239 | fz_try(ctx) | 
|---|
| 240 | { | 
|---|
| 241 | obj = pdf_dict_get(ctx, dict, PDF_NAME(StmF)); | 
|---|
| 242 | if (pdf_is_name(ctx, obj)) | 
|---|
| 243 | pdf_parse_crypt_filter(ctx, &crypt->stmf, crypt, obj); | 
|---|
| 244 |  | 
|---|
| 245 | obj = pdf_dict_get(ctx, dict, PDF_NAME(StrF)); | 
|---|
| 246 | if (pdf_is_name(ctx, obj)) | 
|---|
| 247 | pdf_parse_crypt_filter(ctx, &crypt->strf, crypt, obj); | 
|---|
| 248 | } | 
|---|
| 249 | fz_catch(ctx) | 
|---|
| 250 | { | 
|---|
| 251 | pdf_drop_crypt(ctx, crypt); | 
|---|
| 252 | fz_rethrow(ctx); | 
|---|
| 253 | } | 
|---|
| 254 |  | 
|---|
| 255 | /* in crypt revision 4, the crypt filter determines the key length */ | 
|---|
| 256 | if (crypt->strf.method != PDF_CRYPT_NONE) | 
|---|
| 257 | crypt->length = crypt->stmf.length; | 
|---|
| 258 | } | 
|---|
| 259 |  | 
|---|
| 260 | return crypt; | 
|---|
| 261 | } | 
|---|
| 262 |  | 
|---|
| 263 | void | 
|---|
| 264 | pdf_drop_crypt(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 265 | { | 
|---|
| 266 | if (!crypt) | 
|---|
| 267 | return; | 
|---|
| 268 |  | 
|---|
| 269 | pdf_drop_obj(ctx, crypt->id); | 
|---|
| 270 | pdf_drop_obj(ctx, crypt->cf); | 
|---|
| 271 | fz_free(ctx, crypt); | 
|---|
| 272 | } | 
|---|
| 273 |  | 
|---|
| 274 | /* | 
|---|
| 275 | * Parse a CF dictionary entry (PDF 1.7 table 3.22) | 
|---|
| 276 | */ | 
|---|
| 277 |  | 
|---|
| 278 | static void | 
|---|
| 279 | pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, pdf_crypt *crypt, pdf_obj *name) | 
|---|
| 280 | { | 
|---|
| 281 | pdf_obj *obj; | 
|---|
| 282 | pdf_obj *dict; | 
|---|
| 283 | int is_identity = (pdf_name_eq(ctx, name, PDF_NAME(Identity))); | 
|---|
| 284 | int is_stdcf = (!is_identity && pdf_name_eq(ctx, name, PDF_NAME(StdCF))); | 
|---|
| 285 |  | 
|---|
| 286 | if (!is_identity && !is_stdcf) | 
|---|
| 287 | fz_throw(ctx, FZ_ERROR_GENERIC, "Crypt Filter not Identity or StdCF (%d 0 R)", pdf_to_num(ctx, crypt->cf)); | 
|---|
| 288 |  | 
|---|
| 289 | cf->method = PDF_CRYPT_NONE; | 
|---|
| 290 | cf->length = crypt->length; | 
|---|
| 291 |  | 
|---|
| 292 | if (!crypt->cf) | 
|---|
| 293 | { | 
|---|
| 294 | cf->method = (is_identity ? PDF_CRYPT_NONE : PDF_CRYPT_RC4); | 
|---|
| 295 | return; | 
|---|
| 296 | } | 
|---|
| 297 |  | 
|---|
| 298 | dict = pdf_dict_get(ctx, crypt->cf, name); | 
|---|
| 299 | if (pdf_is_dict(ctx, dict)) | 
|---|
| 300 | { | 
|---|
| 301 | obj = pdf_dict_get(ctx, dict, PDF_NAME(CFM)); | 
|---|
| 302 | if (pdf_is_name(ctx, obj)) | 
|---|
| 303 | { | 
|---|
| 304 | if (pdf_name_eq(ctx, PDF_NAME(None), obj)) | 
|---|
| 305 | cf->method = PDF_CRYPT_NONE; | 
|---|
| 306 | else if (pdf_name_eq(ctx, PDF_NAME(V2), obj)) | 
|---|
| 307 | cf->method = PDF_CRYPT_RC4; | 
|---|
| 308 | else if (pdf_name_eq(ctx, PDF_NAME(AESV2), obj)) | 
|---|
| 309 | cf->method = PDF_CRYPT_AESV2; | 
|---|
| 310 | else if (pdf_name_eq(ctx, PDF_NAME(AESV3), obj)) | 
|---|
| 311 | cf->method = PDF_CRYPT_AESV3; | 
|---|
| 312 | else | 
|---|
| 313 | fz_warn(ctx, "unknown encryption method: %s", pdf_to_name(ctx, obj)); | 
|---|
| 314 | } | 
|---|
| 315 |  | 
|---|
| 316 | obj = pdf_dict_get(ctx, dict, PDF_NAME(Length)); | 
|---|
| 317 | if (pdf_is_int(ctx, obj)) | 
|---|
| 318 | cf->length = pdf_to_int(ctx, obj); | 
|---|
| 319 | } | 
|---|
| 320 | else if (!is_identity) | 
|---|
| 321 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot parse crypt filter (%d 0 R)", pdf_to_num(ctx, crypt->cf)); | 
|---|
| 322 |  | 
|---|
| 323 | /* the length for crypt filters is supposed to be in bytes not bits */ | 
|---|
| 324 | if (cf->length < 40) | 
|---|
| 325 | cf->length = cf->length * 8; | 
|---|
| 326 |  | 
|---|
| 327 | if ((cf->length % 8) != 0) | 
|---|
| 328 | fz_throw(ctx, FZ_ERROR_GENERIC, "invalid key length: %d", cf->length); | 
|---|
| 329 |  | 
|---|
| 330 | if ((crypt->r == 1 || crypt->r == 2 || crypt->r == 3 || crypt->r == 4) && | 
|---|
| 331 | (cf->length < 40 || cf->length > 128)) | 
|---|
| 332 | fz_throw(ctx, FZ_ERROR_GENERIC, "invalid key length: %d", cf->length); | 
|---|
| 333 | if ((crypt->r == 5 || crypt->r == 6) && cf->length != 256) | 
|---|
| 334 | fz_throw(ctx, FZ_ERROR_GENERIC, "invalid key length: %d", cf->length); | 
|---|
| 335 | } | 
|---|
| 336 |  | 
|---|
| 337 | /* | 
|---|
| 338 | * Compute an encryption key (PDF 1.7 algorithm 3.2) | 
|---|
| 339 | */ | 
|---|
| 340 |  | 
|---|
| 341 | static const unsigned char padding[32] = | 
|---|
| 342 | { | 
|---|
| 343 | 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, | 
|---|
| 344 | 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, | 
|---|
| 345 | 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, | 
|---|
| 346 | 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a | 
|---|
| 347 | }; | 
|---|
| 348 |  | 
|---|
| 349 | static void | 
|---|
| 350 | pdf_compute_encryption_key(fz_context *ctx, pdf_crypt *crypt, unsigned char *password, size_t pwlen, unsigned char *key) | 
|---|
| 351 | { | 
|---|
| 352 | unsigned char buf[32]; | 
|---|
| 353 | unsigned int p; | 
|---|
| 354 | int i, n; | 
|---|
| 355 | fz_md5 md5; | 
|---|
| 356 |  | 
|---|
| 357 | n = fz_clampi(crypt->length / 8, 0, 16); | 
|---|
| 358 |  | 
|---|
| 359 | /* Step 1 - copy and pad password string */ | 
|---|
| 360 | if (pwlen > 32) | 
|---|
| 361 | pwlen = 32; | 
|---|
| 362 | memcpy(buf, password, pwlen); | 
|---|
| 363 | memcpy(buf + pwlen, padding, 32 - pwlen); | 
|---|
| 364 |  | 
|---|
| 365 | /* Step 2 - init md5 and pass value of step 1 */ | 
|---|
| 366 | fz_md5_init(&md5); | 
|---|
| 367 | fz_md5_update(&md5, buf, 32); | 
|---|
| 368 |  | 
|---|
| 369 | /* Step 3 - pass O value */ | 
|---|
| 370 | fz_md5_update(&md5, crypt->o, 32); | 
|---|
| 371 |  | 
|---|
| 372 | /* Step 4 - pass P value as unsigned int, low-order byte first */ | 
|---|
| 373 | p = (unsigned int) crypt->p; | 
|---|
| 374 | buf[0] = (p) & 0xFF; | 
|---|
| 375 | buf[1] = (p >> 8) & 0xFF; | 
|---|
| 376 | buf[2] = (p >> 16) & 0xFF; | 
|---|
| 377 | buf[3] = (p >> 24) & 0xFF; | 
|---|
| 378 | fz_md5_update(&md5, buf, 4); | 
|---|
| 379 |  | 
|---|
| 380 | /* Step 5 - pass first element of ID array */ | 
|---|
| 381 | fz_md5_update(&md5, (unsigned char *)pdf_to_str_buf(ctx, crypt->id), pdf_to_str_len(ctx, crypt->id)); | 
|---|
| 382 |  | 
|---|
| 383 | /* Step 6 (revision 4 or greater) - if metadata is not encrypted pass 0xFFFFFFFF */ | 
|---|
| 384 | if (crypt->r >= 4) | 
|---|
| 385 | { | 
|---|
| 386 | if (!crypt->encrypt_metadata) | 
|---|
| 387 | { | 
|---|
| 388 | buf[0] = 0xFF; | 
|---|
| 389 | buf[1] = 0xFF; | 
|---|
| 390 | buf[2] = 0xFF; | 
|---|
| 391 | buf[3] = 0xFF; | 
|---|
| 392 | fz_md5_update(&md5, buf, 4); | 
|---|
| 393 | } | 
|---|
| 394 | } | 
|---|
| 395 |  | 
|---|
| 396 | /* Step 7 - finish the hash */ | 
|---|
| 397 | fz_md5_final(&md5, buf); | 
|---|
| 398 |  | 
|---|
| 399 | /* Step 8 (revision 3 or greater) - do some voodoo 50 times */ | 
|---|
| 400 | if (crypt->r >= 3) | 
|---|
| 401 | { | 
|---|
| 402 | for (i = 0; i < 50; i++) | 
|---|
| 403 | { | 
|---|
| 404 | fz_md5_init(&md5); | 
|---|
| 405 | fz_md5_update(&md5, buf, n); | 
|---|
| 406 | fz_md5_final(&md5, buf); | 
|---|
| 407 | } | 
|---|
| 408 | } | 
|---|
| 409 |  | 
|---|
| 410 | /* Step 9 - the key is the first 'n' bytes of the result */ | 
|---|
| 411 | memcpy(key, buf, n); | 
|---|
| 412 | } | 
|---|
| 413 |  | 
|---|
| 414 | /* | 
|---|
| 415 | * Compute an encryption key (PDF 1.7 ExtensionLevel 3 algorithm 3.2a) | 
|---|
| 416 | */ | 
|---|
| 417 |  | 
|---|
| 418 | static void | 
|---|
| 419 | pdf_compute_encryption_key_r5(fz_context *ctx, pdf_crypt *crypt, unsigned char *password, size_t pwlen, int ownerkey, unsigned char *validationkey) | 
|---|
| 420 | { | 
|---|
| 421 | unsigned char buffer[128 + 8 + 48]; | 
|---|
| 422 | fz_sha256 sha256; | 
|---|
| 423 | fz_aes aes; | 
|---|
| 424 |  | 
|---|
| 425 | /* Step 2 - truncate UTF-8 password to 127 characters */ | 
|---|
| 426 |  | 
|---|
| 427 | if (pwlen > 127) | 
|---|
| 428 | pwlen = 127; | 
|---|
| 429 |  | 
|---|
| 430 | /* Step 3/4 - test password against owner/user key and compute encryption key */ | 
|---|
| 431 |  | 
|---|
| 432 | memcpy(buffer, password, pwlen); | 
|---|
| 433 | if (ownerkey) | 
|---|
| 434 | { | 
|---|
| 435 | memcpy(buffer + pwlen, crypt->o + 32, 8); | 
|---|
| 436 | memcpy(buffer + pwlen + 8, crypt->u, 48); | 
|---|
| 437 | } | 
|---|
| 438 | else | 
|---|
| 439 | memcpy(buffer + pwlen, crypt->u + 32, 8); | 
|---|
| 440 |  | 
|---|
| 441 | fz_sha256_init(&sha256); | 
|---|
| 442 | fz_sha256_update(&sha256, buffer, pwlen + 8 + (ownerkey ? 48 : 0)); | 
|---|
| 443 | fz_sha256_final(&sha256, validationkey); | 
|---|
| 444 |  | 
|---|
| 445 | /* Step 3.5/4.5 - compute file encryption key from OE/UE */ | 
|---|
| 446 |  | 
|---|
| 447 | if (ownerkey) | 
|---|
| 448 | { | 
|---|
| 449 | memcpy(buffer + pwlen, crypt->o + 40, 8); | 
|---|
| 450 | memcpy(buffer + pwlen + 8, crypt->u, 48); | 
|---|
| 451 | } | 
|---|
| 452 | else | 
|---|
| 453 | memcpy(buffer + pwlen, crypt->u + 40, 8); | 
|---|
| 454 |  | 
|---|
| 455 | fz_sha256_init(&sha256); | 
|---|
| 456 | fz_sha256_update(&sha256, buffer, pwlen + 8 + (ownerkey ? 48 : 0)); | 
|---|
| 457 | fz_sha256_final(&sha256, buffer); | 
|---|
| 458 |  | 
|---|
| 459 | /* clear password buffer and use it as iv */ | 
|---|
| 460 | memset(buffer + 32, 0, sizeof(buffer) - 32); | 
|---|
| 461 | if (fz_aes_setkey_dec(&aes, buffer, crypt->length)) | 
|---|
| 462 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", crypt->length); | 
|---|
| 463 | fz_aes_crypt_cbc(&aes, FZ_AES_DECRYPT, 32, buffer + 32, ownerkey ? crypt->oe : crypt->ue, crypt->key); | 
|---|
| 464 | } | 
|---|
| 465 |  | 
|---|
| 466 | /* | 
|---|
| 467 | * Compute an encryption key (PDF 1.7 ExtensionLevel 8 algorithm) | 
|---|
| 468 | * | 
|---|
| 469 | * Adobe has not yet released the details, so the algorithm reference is: | 
|---|
| 470 | * http://esec-lab.sogeti.com/post/The-undocumented-password-validation-algorithm-of-Adobe-Reader-X | 
|---|
| 471 | */ | 
|---|
| 472 |  | 
|---|
| 473 | static void | 
|---|
| 474 | pdf_compute_hardened_hash_r6(fz_context *ctx, unsigned char *password, size_t pwlen, unsigned char salt[8], unsigned char *ownerkey, unsigned char hash[32]) | 
|---|
| 475 | { | 
|---|
| 476 | unsigned char data[(128 + 64 + 48) * 64]; | 
|---|
| 477 | unsigned char block[64]; | 
|---|
| 478 | int block_size = 32; | 
|---|
| 479 | size_t data_len = 0; | 
|---|
| 480 | int i, j, sum; | 
|---|
| 481 |  | 
|---|
| 482 | fz_sha256 sha256; | 
|---|
| 483 | fz_sha384 sha384; | 
|---|
| 484 | fz_sha512 sha512; | 
|---|
| 485 | fz_aes aes; | 
|---|
| 486 |  | 
|---|
| 487 | /* Step 1: calculate initial data block */ | 
|---|
| 488 | fz_sha256_init(&sha256); | 
|---|
| 489 | fz_sha256_update(&sha256, password, pwlen); | 
|---|
| 490 | fz_sha256_update(&sha256, salt, 8); | 
|---|
| 491 | if (ownerkey) | 
|---|
| 492 | fz_sha256_update(&sha256, ownerkey, 48); | 
|---|
| 493 | fz_sha256_final(&sha256, block); | 
|---|
| 494 |  | 
|---|
| 495 | for (i = 0; i < 64 || i < data[data_len * 64 - 1] + 32; i++) | 
|---|
| 496 | { | 
|---|
| 497 | /* Step 2: repeat password and data block 64 times */ | 
|---|
| 498 | memcpy(data, password, pwlen); | 
|---|
| 499 | memcpy(data + pwlen, block, block_size); | 
|---|
| 500 | if (ownerkey) | 
|---|
| 501 | memcpy(data + pwlen + block_size, ownerkey, 48); | 
|---|
| 502 | data_len = pwlen + block_size + (ownerkey ? 48 : 0); | 
|---|
| 503 | for (j = 1; j < 64; j++) | 
|---|
| 504 | memcpy(data + j * data_len, data, data_len); | 
|---|
| 505 |  | 
|---|
| 506 | /* Step 3: encrypt data using data block as key and iv */ | 
|---|
| 507 | if (fz_aes_setkey_enc(&aes, block, 128)) | 
|---|
| 508 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", 128); | 
|---|
| 509 | fz_aes_crypt_cbc(&aes, FZ_AES_ENCRYPT, data_len * 64, block + 16, data, data); | 
|---|
| 510 |  | 
|---|
| 511 | /* Step 4: determine SHA-2 hash size for this round */ | 
|---|
| 512 | for (j = 0, sum = 0; j < 16; j++) | 
|---|
| 513 | sum += data[j]; | 
|---|
| 514 |  | 
|---|
| 515 | /* Step 5: calculate data block for next round */ | 
|---|
| 516 | block_size = 32 + (sum % 3) * 16; | 
|---|
| 517 | switch (block_size) | 
|---|
| 518 | { | 
|---|
| 519 | case 32: | 
|---|
| 520 | fz_sha256_init(&sha256); | 
|---|
| 521 | fz_sha256_update(&sha256, data, data_len * 64); | 
|---|
| 522 | fz_sha256_final(&sha256, block); | 
|---|
| 523 | break; | 
|---|
| 524 | case 48: | 
|---|
| 525 | fz_sha384_init(&sha384); | 
|---|
| 526 | fz_sha384_update(&sha384, data, data_len * 64); | 
|---|
| 527 | fz_sha384_final(&sha384, block); | 
|---|
| 528 | break; | 
|---|
| 529 | case 64: | 
|---|
| 530 | fz_sha512_init(&sha512); | 
|---|
| 531 | fz_sha512_update(&sha512, data, data_len * 64); | 
|---|
| 532 | fz_sha512_final(&sha512, block); | 
|---|
| 533 | break; | 
|---|
| 534 | } | 
|---|
| 535 | } | 
|---|
| 536 |  | 
|---|
| 537 | memset(data, 0, sizeof(data)); | 
|---|
| 538 | memcpy(hash, block, 32); | 
|---|
| 539 | } | 
|---|
| 540 |  | 
|---|
| 541 | static void | 
|---|
| 542 | pdf_compute_encryption_key_r6(fz_context *ctx, pdf_crypt *crypt, unsigned char *password, size_t pwlen, int ownerkey, unsigned char *validationkey) | 
|---|
| 543 | { | 
|---|
| 544 | unsigned char hash[32]; | 
|---|
| 545 | unsigned char iv[16]; | 
|---|
| 546 | fz_aes aes; | 
|---|
| 547 |  | 
|---|
| 548 | if (pwlen > 127) | 
|---|
| 549 | pwlen = 127; | 
|---|
| 550 |  | 
|---|
| 551 | pdf_compute_hardened_hash_r6(ctx, password, pwlen, | 
|---|
| 552 | (ownerkey ? crypt->o : crypt->u) + 32, | 
|---|
| 553 | ownerkey ? crypt->u : NULL, validationkey); | 
|---|
| 554 | pdf_compute_hardened_hash_r6(ctx, password, pwlen, | 
|---|
| 555 | (ownerkey ? crypt->o : crypt->u) + 40, | 
|---|
| 556 | (ownerkey ? crypt->u : NULL), | 
|---|
| 557 | hash); | 
|---|
| 558 |  | 
|---|
| 559 | memset(iv, 0, sizeof(iv)); | 
|---|
| 560 | if (fz_aes_setkey_dec(&aes, hash, 256)) | 
|---|
| 561 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=256)"); | 
|---|
| 562 | fz_aes_crypt_cbc(&aes, FZ_AES_DECRYPT, 32, iv, ownerkey ? crypt->oe : crypt->ue, crypt->key); | 
|---|
| 563 | } | 
|---|
| 564 |  | 
|---|
| 565 | /* | 
|---|
| 566 | * Computing the user password (PDF 1.7 algorithm 3.4 and 3.5) | 
|---|
| 567 | * Also save the generated key for decrypting objects and streams in crypt->key. | 
|---|
| 568 | */ | 
|---|
| 569 |  | 
|---|
| 570 | static void | 
|---|
| 571 | pdf_compute_user_password(fz_context *ctx, pdf_crypt *crypt, unsigned char *password, size_t pwlen, unsigned char *output) | 
|---|
| 572 | { | 
|---|
| 573 | int n = fz_clampi(crypt->length / 8, 0, 16); | 
|---|
| 574 |  | 
|---|
| 575 | if (crypt->r == 2) | 
|---|
| 576 | { | 
|---|
| 577 | fz_arc4 arc4; | 
|---|
| 578 |  | 
|---|
| 579 | pdf_compute_encryption_key(ctx, crypt, password, pwlen, crypt->key); | 
|---|
| 580 | fz_arc4_init(&arc4, crypt->key, n); | 
|---|
| 581 | fz_arc4_encrypt(&arc4, output, padding, 32); | 
|---|
| 582 | } | 
|---|
| 583 |  | 
|---|
| 584 | if (crypt->r == 3 || crypt->r == 4) | 
|---|
| 585 | { | 
|---|
| 586 | unsigned char xor[32]; | 
|---|
| 587 | unsigned char digest[16]; | 
|---|
| 588 | fz_md5 md5; | 
|---|
| 589 | fz_arc4 arc4; | 
|---|
| 590 | int i, x; | 
|---|
| 591 |  | 
|---|
| 592 | pdf_compute_encryption_key(ctx, crypt, password, pwlen, crypt->key); | 
|---|
| 593 |  | 
|---|
| 594 | fz_md5_init(&md5); | 
|---|
| 595 | fz_md5_update(&md5, padding, 32); | 
|---|
| 596 | fz_md5_update(&md5, (unsigned char*)pdf_to_str_buf(ctx, crypt->id), pdf_to_str_len(ctx, crypt->id)); | 
|---|
| 597 | fz_md5_final(&md5, digest); | 
|---|
| 598 |  | 
|---|
| 599 | fz_arc4_init(&arc4, crypt->key, n); | 
|---|
| 600 | fz_arc4_encrypt(&arc4, output, digest, 16); | 
|---|
| 601 |  | 
|---|
| 602 | for (x = 1; x <= 19; x++) | 
|---|
| 603 | { | 
|---|
| 604 | for (i = 0; i < n; i++) | 
|---|
| 605 | xor[i] = crypt->key[i] ^ x; | 
|---|
| 606 | fz_arc4_init(&arc4, xor, n); | 
|---|
| 607 | fz_arc4_encrypt(&arc4, output, output, 16); | 
|---|
| 608 | } | 
|---|
| 609 |  | 
|---|
| 610 | memcpy(output + 16, padding, 16); | 
|---|
| 611 | } | 
|---|
| 612 |  | 
|---|
| 613 | if (crypt->r == 5) | 
|---|
| 614 | { | 
|---|
| 615 | pdf_compute_encryption_key_r5(ctx, crypt, password, pwlen, 0, output); | 
|---|
| 616 | } | 
|---|
| 617 |  | 
|---|
| 618 | if (crypt->r == 6) | 
|---|
| 619 | { | 
|---|
| 620 | pdf_compute_encryption_key_r6(ctx, crypt, password, pwlen, 0, output); | 
|---|
| 621 | } | 
|---|
| 622 | } | 
|---|
| 623 |  | 
|---|
| 624 | /* | 
|---|
| 625 | * Authenticating the user password (PDF 1.7 algorithm 3.6 | 
|---|
| 626 | * and ExtensionLevel 3 algorithm 3.11) | 
|---|
| 627 | * This also has the side effect of saving a key generated | 
|---|
| 628 | * from the password for decrypting objects and streams. | 
|---|
| 629 | */ | 
|---|
| 630 |  | 
|---|
| 631 | static int | 
|---|
| 632 | pdf_authenticate_user_password(fz_context *ctx, pdf_crypt *crypt, unsigned char *password, size_t pwlen) | 
|---|
| 633 | { | 
|---|
| 634 | unsigned char output[32]; | 
|---|
| 635 | pdf_compute_user_password(ctx, crypt, password, pwlen, output); | 
|---|
| 636 | if (crypt->r == 2 || crypt->r == 5 || crypt->r == 6) | 
|---|
| 637 | return memcmp(output, crypt->u, 32) == 0; | 
|---|
| 638 | if (crypt->r == 3 || crypt->r == 4) | 
|---|
| 639 | return memcmp(output, crypt->u, 16) == 0; | 
|---|
| 640 | return 0; | 
|---|
| 641 | } | 
|---|
| 642 |  | 
|---|
| 643 | /* | 
|---|
| 644 | * Authenticating the owner password (PDF 1.7 algorithm 3.7, | 
|---|
| 645 | * ExtensionLevel 3 algorithm 3.12, ExtensionLevel 8 algorithm) | 
|---|
| 646 | * Generates the user password from the owner password | 
|---|
| 647 | * and calls pdf_authenticate_user_password. | 
|---|
| 648 | */ | 
|---|
| 649 |  | 
|---|
| 650 | static int | 
|---|
| 651 | pdf_authenticate_owner_password(fz_context *ctx, pdf_crypt *crypt, unsigned char *ownerpass, size_t pwlen) | 
|---|
| 652 | { | 
|---|
| 653 | int n = fz_clampi(crypt->length / 8, 0, 16); | 
|---|
| 654 |  | 
|---|
| 655 | if (crypt->r == 2) | 
|---|
| 656 | { | 
|---|
| 657 | unsigned char pwbuf[32]; | 
|---|
| 658 | unsigned char key[16]; | 
|---|
| 659 | unsigned char userpass[32]; | 
|---|
| 660 | fz_md5 md5; | 
|---|
| 661 | fz_arc4 arc4; | 
|---|
| 662 |  | 
|---|
| 663 | if (pwlen > 32) | 
|---|
| 664 | pwlen = 32; | 
|---|
| 665 | memcpy(pwbuf, ownerpass, pwlen); | 
|---|
| 666 | memcpy(pwbuf + pwlen, padding, 32 - pwlen); | 
|---|
| 667 |  | 
|---|
| 668 | fz_md5_init(&md5); | 
|---|
| 669 | fz_md5_update(&md5, pwbuf, 32); | 
|---|
| 670 | fz_md5_final(&md5, key); | 
|---|
| 671 |  | 
|---|
| 672 | fz_arc4_init(&arc4, key, n); | 
|---|
| 673 | fz_arc4_encrypt(&arc4, userpass, crypt->o, 32); | 
|---|
| 674 |  | 
|---|
| 675 | return pdf_authenticate_user_password(ctx, crypt, userpass, 32); | 
|---|
| 676 | } | 
|---|
| 677 |  | 
|---|
| 678 | if (crypt->r == 3 || crypt->r == 4) | 
|---|
| 679 | { | 
|---|
| 680 | unsigned char pwbuf[32]; | 
|---|
| 681 | unsigned char key[16]; | 
|---|
| 682 | unsigned char xor[32]; | 
|---|
| 683 | unsigned char userpass[32]; | 
|---|
| 684 | int i, x; | 
|---|
| 685 | fz_md5 md5; | 
|---|
| 686 | fz_arc4 arc4; | 
|---|
| 687 |  | 
|---|
| 688 | if (pwlen > 32) | 
|---|
| 689 | pwlen = 32; | 
|---|
| 690 | memcpy(pwbuf, ownerpass, pwlen); | 
|---|
| 691 | memcpy(pwbuf + pwlen, padding, 32 - pwlen); | 
|---|
| 692 |  | 
|---|
| 693 | fz_md5_init(&md5); | 
|---|
| 694 | fz_md5_update(&md5, pwbuf, 32); | 
|---|
| 695 | fz_md5_final(&md5, key); | 
|---|
| 696 |  | 
|---|
| 697 | for (i = 0; i < 50; i++) | 
|---|
| 698 | { | 
|---|
| 699 | fz_md5_init(&md5); | 
|---|
| 700 | fz_md5_update(&md5, key, n); | 
|---|
| 701 | fz_md5_final(&md5, key); | 
|---|
| 702 | } | 
|---|
| 703 |  | 
|---|
| 704 | memcpy(userpass, crypt->o, 32); | 
|---|
| 705 | for (x = 0; x < 20; x++) | 
|---|
| 706 | { | 
|---|
| 707 | for (i = 0; i < n; i++) | 
|---|
| 708 | xor[i] = key[i] ^ (19 - x); | 
|---|
| 709 | fz_arc4_init(&arc4, xor, n); | 
|---|
| 710 | fz_arc4_encrypt(&arc4, userpass, userpass, 32); | 
|---|
| 711 | } | 
|---|
| 712 |  | 
|---|
| 713 | return pdf_authenticate_user_password(ctx, crypt, userpass, 32); | 
|---|
| 714 | } | 
|---|
| 715 |  | 
|---|
| 716 | if (crypt->r == 5) | 
|---|
| 717 | { | 
|---|
| 718 | unsigned char key[32]; | 
|---|
| 719 | pdf_compute_encryption_key_r5(ctx, crypt, ownerpass, pwlen, 1, key); | 
|---|
| 720 | return !memcmp(key, crypt->o, 32); | 
|---|
| 721 | } | 
|---|
| 722 |  | 
|---|
| 723 | if (crypt->r == 6) | 
|---|
| 724 | { | 
|---|
| 725 | unsigned char key[32]; | 
|---|
| 726 | pdf_compute_encryption_key_r6(ctx, crypt, ownerpass, pwlen, 1, key); | 
|---|
| 727 | return !memcmp(key, crypt->o, 32); | 
|---|
| 728 | } | 
|---|
| 729 |  | 
|---|
| 730 | return 0; | 
|---|
| 731 | } | 
|---|
| 732 |  | 
|---|
| 733 | static void pdf_docenc_from_utf8(char *password, const char *utf8, int n) | 
|---|
| 734 | { | 
|---|
| 735 | int i = 0, k, c; | 
|---|
| 736 | while (*utf8 && i + 1 < n) | 
|---|
| 737 | { | 
|---|
| 738 | utf8 += fz_chartorune(&c, utf8); | 
|---|
| 739 | for (k = 0; k < 256; k++) | 
|---|
| 740 | { | 
|---|
| 741 | if (c == fz_unicode_from_pdf_doc_encoding[k]) | 
|---|
| 742 | { | 
|---|
| 743 | password[i++] = k; | 
|---|
| 744 | break; | 
|---|
| 745 | } | 
|---|
| 746 | } | 
|---|
| 747 | /* FIXME: drop characters that can't be encoded or return an error? */ | 
|---|
| 748 | } | 
|---|
| 749 | password[i] = 0; | 
|---|
| 750 | } | 
|---|
| 751 |  | 
|---|
| 752 | static void pdf_saslprep_from_utf8(char *password, const char *utf8, int n) | 
|---|
| 753 | { | 
|---|
| 754 | /* TODO: stringprep with SALSprep profile */ | 
|---|
| 755 | fz_strlcpy(password, utf8, n); | 
|---|
| 756 | } | 
|---|
| 757 |  | 
|---|
| 758 | /* | 
|---|
| 759 | Attempt to authenticate a | 
|---|
| 760 | password. | 
|---|
| 761 |  | 
|---|
| 762 | Returns 0 for failure, non-zero for success. | 
|---|
| 763 |  | 
|---|
| 764 | In the non-zero case: | 
|---|
| 765 | bit 0 set => no password required | 
|---|
| 766 | bit 1 set => user password authenticated | 
|---|
| 767 | bit 2 set => owner password authenticated | 
|---|
| 768 | */ | 
|---|
| 769 | int | 
|---|
| 770 | pdf_authenticate_password(fz_context *ctx, pdf_document *doc, const char *pwd_utf8) | 
|---|
| 771 | { | 
|---|
| 772 | char password[2048]; | 
|---|
| 773 | int auth; | 
|---|
| 774 |  | 
|---|
| 775 | if (!doc->crypt) | 
|---|
| 776 | return 1; /* No password required */ | 
|---|
| 777 |  | 
|---|
| 778 | password[0] = 0; | 
|---|
| 779 | if (pwd_utf8) | 
|---|
| 780 | { | 
|---|
| 781 | if (doc->crypt->r <= 4) | 
|---|
| 782 | pdf_docenc_from_utf8(password, pwd_utf8, sizeof password); | 
|---|
| 783 | else | 
|---|
| 784 | pdf_saslprep_from_utf8(password, pwd_utf8, sizeof password); | 
|---|
| 785 | } | 
|---|
| 786 |  | 
|---|
| 787 | auth = 0; | 
|---|
| 788 | if (pdf_authenticate_user_password(ctx, doc->crypt, (unsigned char *)password, strlen(password))) | 
|---|
| 789 | auth = 2; | 
|---|
| 790 | if (pdf_authenticate_owner_password(ctx, doc->crypt, (unsigned char *)password, strlen(password))) | 
|---|
| 791 | auth |= 4; | 
|---|
| 792 | else if (auth & 2) | 
|---|
| 793 | { | 
|---|
| 794 | /* We need to reauthenticate the user password, | 
|---|
| 795 | * because the failed attempt to authenticate | 
|---|
| 796 | * the owner password will have invalidated the | 
|---|
| 797 | * stored keys. */ | 
|---|
| 798 | (void)pdf_authenticate_user_password(ctx, doc->crypt, (unsigned char *)password, strlen(password)); | 
|---|
| 799 | } | 
|---|
| 800 |  | 
|---|
| 801 | /* To match Acrobat, we choose not to allow an empty owner | 
|---|
| 802 | * password, unless the user password is also the empty one. */ | 
|---|
| 803 | if (*password == 0 && auth == 4) | 
|---|
| 804 | return 0; | 
|---|
| 805 |  | 
|---|
| 806 | return auth; | 
|---|
| 807 | } | 
|---|
| 808 |  | 
|---|
| 809 | int | 
|---|
| 810 | pdf_needs_password(fz_context *ctx, pdf_document *doc) | 
|---|
| 811 | { | 
|---|
| 812 | if (!doc->crypt) | 
|---|
| 813 | return 0; | 
|---|
| 814 | if (pdf_authenticate_password(ctx, doc, "")) | 
|---|
| 815 | return 0; | 
|---|
| 816 | return 1; | 
|---|
| 817 | } | 
|---|
| 818 |  | 
|---|
| 819 | int | 
|---|
| 820 | pdf_has_permission(fz_context *ctx, pdf_document *doc, fz_permission p) | 
|---|
| 821 | { | 
|---|
| 822 | if (!doc->crypt) | 
|---|
| 823 | return 1; | 
|---|
| 824 | switch (p) | 
|---|
| 825 | { | 
|---|
| 826 | case FZ_PERMISSION_PRINT: return doc->crypt->p & PDF_PERM_PRINT; | 
|---|
| 827 | case FZ_PERMISSION_COPY: return doc->crypt->p & PDF_PERM_COPY; | 
|---|
| 828 | case FZ_PERMISSION_EDIT: return doc->crypt->p & PDF_PERM_MODIFY; | 
|---|
| 829 | case FZ_PERMISSION_ANNOTATE: return doc->crypt->p & PDF_PERM_ANNOTATE; | 
|---|
| 830 | } | 
|---|
| 831 | return 1; | 
|---|
| 832 | } | 
|---|
| 833 |  | 
|---|
| 834 | int | 
|---|
| 835 | pdf_document_permissions(fz_context *ctx, pdf_document *doc) | 
|---|
| 836 | { | 
|---|
| 837 | if (doc->crypt) | 
|---|
| 838 | return doc->crypt->p; | 
|---|
| 839 | /* all permissions granted, reserved bits set appropriately */ | 
|---|
| 840 | return (int)0xFFFFFFFC; | 
|---|
| 841 | } | 
|---|
| 842 |  | 
|---|
| 843 | /* | 
|---|
| 844 | * Compute the owner password (PDF 1.7 algorithm 3.3) | 
|---|
| 845 | */ | 
|---|
| 846 |  | 
|---|
| 847 | static void | 
|---|
| 848 | pdf_compute_owner_password(fz_context *ctx, pdf_crypt *crypt, unsigned char *opassword, size_t opwlen, unsigned char *upassword, size_t upwlen, unsigned char *output) | 
|---|
| 849 | { | 
|---|
| 850 | unsigned char obuf[32]; | 
|---|
| 851 | unsigned char ubuf[32]; | 
|---|
| 852 | unsigned char digest[32]; | 
|---|
| 853 | int i, n; | 
|---|
| 854 | fz_md5 md5; | 
|---|
| 855 | fz_arc4 arc4; | 
|---|
| 856 |  | 
|---|
| 857 | n = fz_clampi(crypt->length / 8, 0, 16); | 
|---|
| 858 |  | 
|---|
| 859 | /* Step 1 - copy and pad owner password string */ | 
|---|
| 860 | if (opwlen > 32) | 
|---|
| 861 | opwlen = 32; | 
|---|
| 862 | memcpy(obuf, opassword, opwlen); | 
|---|
| 863 | memcpy(obuf + opwlen, padding, 32 - opwlen); | 
|---|
| 864 |  | 
|---|
| 865 | /* Step 2 - init md5 and pass value of step 1 */ | 
|---|
| 866 | fz_md5_init(&md5); | 
|---|
| 867 | fz_md5_update(&md5, obuf, 32); | 
|---|
| 868 | fz_md5_final(&md5, obuf); | 
|---|
| 869 |  | 
|---|
| 870 | /* Step 3 (revision 3 or greater) - do some voodoo 50 times */ | 
|---|
| 871 | if (crypt->r >= 3) | 
|---|
| 872 | { | 
|---|
| 873 | for (i = 0; i < 50; i++) | 
|---|
| 874 | { | 
|---|
| 875 | fz_md5_init(&md5); | 
|---|
| 876 | fz_md5_update(&md5, obuf, n); | 
|---|
| 877 | fz_md5_final(&md5, obuf); | 
|---|
| 878 | } | 
|---|
| 879 | } | 
|---|
| 880 |  | 
|---|
| 881 | /* Step 4 - encrypt owner password md5 hash */ | 
|---|
| 882 | fz_arc4_init(&arc4, obuf, n); | 
|---|
| 883 |  | 
|---|
| 884 | /* Step 5 - copy and pad user password string */ | 
|---|
| 885 | if (upwlen > 32) | 
|---|
| 886 | upwlen = 32; | 
|---|
| 887 | memcpy(ubuf, upassword, upwlen); | 
|---|
| 888 | memcpy(ubuf + upwlen, padding, 32 - upwlen); | 
|---|
| 889 |  | 
|---|
| 890 | /* Step 6 - encrypt user password md5 hash */ | 
|---|
| 891 | fz_arc4_encrypt(&arc4, digest, ubuf, 32); | 
|---|
| 892 |  | 
|---|
| 893 | /* Step 7 - */ | 
|---|
| 894 | if (crypt->r >= 3) | 
|---|
| 895 | { | 
|---|
| 896 | unsigned char xor[32]; | 
|---|
| 897 | int x; | 
|---|
| 898 |  | 
|---|
| 899 | for (x = 1; x <= 19; x++) | 
|---|
| 900 | { | 
|---|
| 901 | for (i = 0; i < n; i++) | 
|---|
| 902 | xor[i] = obuf[i] ^ x; | 
|---|
| 903 | fz_arc4_init(&arc4, xor, n); | 
|---|
| 904 | fz_arc4_encrypt(&arc4, digest, digest, 32); | 
|---|
| 905 | } | 
|---|
| 906 | } | 
|---|
| 907 |  | 
|---|
| 908 | /* Step 8 - the owner password is the first 16 bytes of the result */ | 
|---|
| 909 | memcpy(output, digest, 32); | 
|---|
| 910 | } | 
|---|
| 911 |  | 
|---|
| 912 | unsigned char * | 
|---|
| 913 | pdf_crypt_key(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 914 | { | 
|---|
| 915 | if (crypt) | 
|---|
| 916 | return crypt->key; | 
|---|
| 917 | return NULL; | 
|---|
| 918 | } | 
|---|
| 919 |  | 
|---|
| 920 | int | 
|---|
| 921 | pdf_crypt_version(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 922 | { | 
|---|
| 923 | if (crypt) | 
|---|
| 924 | return crypt->v; | 
|---|
| 925 | return 0; | 
|---|
| 926 | } | 
|---|
| 927 |  | 
|---|
| 928 | int pdf_crypt_revision(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 929 | { | 
|---|
| 930 | if (crypt) | 
|---|
| 931 | return crypt->r; | 
|---|
| 932 | return 0; | 
|---|
| 933 | } | 
|---|
| 934 |  | 
|---|
| 935 | char * | 
|---|
| 936 | pdf_crypt_method(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 937 | { | 
|---|
| 938 | if (crypt) | 
|---|
| 939 | { | 
|---|
| 940 | switch (crypt->strf.method) | 
|---|
| 941 | { | 
|---|
| 942 | case PDF_CRYPT_NONE: return "None"; | 
|---|
| 943 | case PDF_CRYPT_RC4: return "RC4"; | 
|---|
| 944 | case PDF_CRYPT_AESV2: return "AES"; | 
|---|
| 945 | case PDF_CRYPT_AESV3: return "AES"; | 
|---|
| 946 | case PDF_CRYPT_UNKNOWN: return "Unknown"; | 
|---|
| 947 | } | 
|---|
| 948 | } | 
|---|
| 949 | return "None"; | 
|---|
| 950 | } | 
|---|
| 951 |  | 
|---|
| 952 | int | 
|---|
| 953 | pdf_crypt_length(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 954 | { | 
|---|
| 955 | if (crypt) | 
|---|
| 956 | return crypt->length; | 
|---|
| 957 | return 0; | 
|---|
| 958 | } | 
|---|
| 959 |  | 
|---|
| 960 | int | 
|---|
| 961 | pdf_crypt_permissions(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 962 | { | 
|---|
| 963 | if (crypt) | 
|---|
| 964 | return crypt->p; | 
|---|
| 965 | return 0; | 
|---|
| 966 | } | 
|---|
| 967 |  | 
|---|
| 968 | int | 
|---|
| 969 | pdf_crypt_encrypt_metadata(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 970 | { | 
|---|
| 971 | if (crypt) | 
|---|
| 972 | return crypt->encrypt_metadata; | 
|---|
| 973 | return 0; | 
|---|
| 974 | } | 
|---|
| 975 |  | 
|---|
| 976 | unsigned char * | 
|---|
| 977 | pdf_crypt_owner_password(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 978 | { | 
|---|
| 979 | if (crypt) | 
|---|
| 980 | return crypt->o; | 
|---|
| 981 | return NULL; | 
|---|
| 982 | } | 
|---|
| 983 |  | 
|---|
| 984 | unsigned char * | 
|---|
| 985 | pdf_crypt_user_password(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 986 | { | 
|---|
| 987 | if (crypt) | 
|---|
| 988 | return crypt->u; | 
|---|
| 989 | return NULL; | 
|---|
| 990 | } | 
|---|
| 991 |  | 
|---|
| 992 | unsigned char * | 
|---|
| 993 | pdf_crypt_owner_encryption(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 994 | { | 
|---|
| 995 | if (crypt) | 
|---|
| 996 | return crypt->oe; | 
|---|
| 997 | return NULL; | 
|---|
| 998 | } | 
|---|
| 999 |  | 
|---|
| 1000 | unsigned char * | 
|---|
| 1001 | pdf_crypt_user_encryption(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 1002 | { | 
|---|
| 1003 | if (crypt) | 
|---|
| 1004 | return crypt->ue; | 
|---|
| 1005 | return NULL; | 
|---|
| 1006 | } | 
|---|
| 1007 |  | 
|---|
| 1008 | unsigned char * | 
|---|
| 1009 | pdf_crypt_permissions_encryption(fz_context *ctx, pdf_crypt *crypt) | 
|---|
| 1010 | { | 
|---|
| 1011 | if (crypt) | 
|---|
| 1012 | return crypt->perms; | 
|---|
| 1013 | return 0; | 
|---|
| 1014 | } | 
|---|
| 1015 |  | 
|---|
| 1016 | /* | 
|---|
| 1017 | * PDF 1.7 algorithm 3.1 and ExtensionLevel 3 algorithm 3.1a | 
|---|
| 1018 | * | 
|---|
| 1019 | * Using the global encryption key that was generated from the | 
|---|
| 1020 | * password, create a new key that is used to decrypt individual | 
|---|
| 1021 | * objects and streams. This key is based on the object and | 
|---|
| 1022 | * generation numbers. | 
|---|
| 1023 | */ | 
|---|
| 1024 |  | 
|---|
| 1025 | static int | 
|---|
| 1026 | pdf_compute_object_key(pdf_crypt *crypt, pdf_crypt_filter *cf, int num, int gen, unsigned char *key, int max_len) | 
|---|
| 1027 | { | 
|---|
| 1028 | fz_md5 md5; | 
|---|
| 1029 | unsigned char message[5]; | 
|---|
| 1030 | int key_len = crypt->length / 8; | 
|---|
| 1031 |  | 
|---|
| 1032 | if (key_len > max_len) | 
|---|
| 1033 | key_len = max_len; | 
|---|
| 1034 |  | 
|---|
| 1035 | /* Encryption method version 0 is undocumented, but a lucky | 
|---|
| 1036 | guess revealed that all streams/strings in those PDFs are | 
|---|
| 1037 | encrypted using the same 40 bit file enryption key using RC4. */ | 
|---|
| 1038 | if (crypt->v == 0 || cf->method == PDF_CRYPT_AESV3) | 
|---|
| 1039 | { | 
|---|
| 1040 | memcpy(key, crypt->key, key_len); | 
|---|
| 1041 | return key_len; | 
|---|
| 1042 | } | 
|---|
| 1043 |  | 
|---|
| 1044 | fz_md5_init(&md5); | 
|---|
| 1045 | fz_md5_update(&md5, crypt->key, key_len); | 
|---|
| 1046 | message[0] = (num) & 0xFF; | 
|---|
| 1047 | message[1] = (num >> 8) & 0xFF; | 
|---|
| 1048 | message[2] = (num >> 16) & 0xFF; | 
|---|
| 1049 | message[3] = (gen) & 0xFF; | 
|---|
| 1050 | message[4] = (gen >> 8) & 0xFF; | 
|---|
| 1051 | fz_md5_update(&md5, message, 5); | 
|---|
| 1052 |  | 
|---|
| 1053 | if (cf->method == PDF_CRYPT_AESV2) | 
|---|
| 1054 | fz_md5_update(&md5, (unsigned char *) "sAlT", 4); | 
|---|
| 1055 |  | 
|---|
| 1056 | fz_md5_final(&md5, key); | 
|---|
| 1057 |  | 
|---|
| 1058 | if (key_len + 5 > 16) | 
|---|
| 1059 | return 16; | 
|---|
| 1060 | return key_len + 5; | 
|---|
| 1061 | } | 
|---|
| 1062 |  | 
|---|
| 1063 | /* | 
|---|
| 1064 | * PDF 1.7 algorithm 3.1 and ExtensionLevel 3 algorithm 3.1a | 
|---|
| 1065 | * | 
|---|
| 1066 | * Decrypt all strings in obj modifying the data in-place. | 
|---|
| 1067 | * Recurse through arrays and dictionaries, but do not follow | 
|---|
| 1068 | * indirect references. | 
|---|
| 1069 | */ | 
|---|
| 1070 |  | 
|---|
| 1071 | static void | 
|---|
| 1072 | pdf_crypt_obj_imp(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, unsigned char *key, int keylen) | 
|---|
| 1073 | { | 
|---|
| 1074 | unsigned char *s; | 
|---|
| 1075 | int i, n; | 
|---|
| 1076 |  | 
|---|
| 1077 | if (pdf_is_indirect(ctx, obj)) | 
|---|
| 1078 | return; | 
|---|
| 1079 |  | 
|---|
| 1080 | if (pdf_is_string(ctx, obj)) | 
|---|
| 1081 | { | 
|---|
| 1082 | s = (unsigned char *)pdf_to_str_buf(ctx, obj); | 
|---|
| 1083 | n = pdf_to_str_len(ctx, obj); | 
|---|
| 1084 |  | 
|---|
| 1085 | if (crypt->strf.method == PDF_CRYPT_RC4) | 
|---|
| 1086 | { | 
|---|
| 1087 | fz_arc4 arc4; | 
|---|
| 1088 | fz_arc4_init(&arc4, key, keylen); | 
|---|
| 1089 | fz_arc4_encrypt(&arc4, s, s, n); | 
|---|
| 1090 | } | 
|---|
| 1091 |  | 
|---|
| 1092 | if (crypt->strf.method == PDF_CRYPT_AESV2 || crypt->strf.method == PDF_CRYPT_AESV3) | 
|---|
| 1093 | { | 
|---|
| 1094 | if (n == 0) | 
|---|
| 1095 | { | 
|---|
| 1096 | /* Empty strings are permissible */ | 
|---|
| 1097 | } | 
|---|
| 1098 | else if (n & 15 || n < 32) | 
|---|
| 1099 | fz_warn(ctx, "invalid string length for aes encryption"); | 
|---|
| 1100 | else | 
|---|
| 1101 | { | 
|---|
| 1102 | unsigned char iv[16]; | 
|---|
| 1103 | fz_aes aes; | 
|---|
| 1104 | memcpy(iv, s, 16); | 
|---|
| 1105 | if (fz_aes_setkey_dec(&aes, key, keylen * 8)) | 
|---|
| 1106 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", keylen * 8); | 
|---|
| 1107 | fz_aes_crypt_cbc(&aes, FZ_AES_DECRYPT, n - 16, iv, s + 16, s); | 
|---|
| 1108 | /* delete space used for iv and padding bytes at end */ | 
|---|
| 1109 | if (s[n - 17] < 1 || s[n - 17] > 16) | 
|---|
| 1110 | fz_warn(ctx, "aes padding out of range"); | 
|---|
| 1111 | else | 
|---|
| 1112 | pdf_set_str_len(ctx, obj, n - 16 - s[n - 17]); | 
|---|
| 1113 | } | 
|---|
| 1114 | } | 
|---|
| 1115 | } | 
|---|
| 1116 |  | 
|---|
| 1117 | else if (pdf_is_array(ctx, obj)) | 
|---|
| 1118 | { | 
|---|
| 1119 | n = pdf_array_len(ctx, obj); | 
|---|
| 1120 | for (i = 0; i < n; i++) | 
|---|
| 1121 | { | 
|---|
| 1122 | pdf_crypt_obj_imp(ctx, crypt, pdf_array_get(ctx, obj, i), key, keylen); | 
|---|
| 1123 | } | 
|---|
| 1124 | } | 
|---|
| 1125 |  | 
|---|
| 1126 | else if (pdf_is_dict(ctx, obj)) | 
|---|
| 1127 | { | 
|---|
| 1128 | n = pdf_dict_len(ctx, obj); | 
|---|
| 1129 | for (i = 0; i < n; i++) | 
|---|
| 1130 | { | 
|---|
| 1131 | pdf_crypt_obj_imp(ctx, crypt, pdf_dict_get_val(ctx, obj, i), key, keylen); | 
|---|
| 1132 | } | 
|---|
| 1133 | } | 
|---|
| 1134 | } | 
|---|
| 1135 |  | 
|---|
| 1136 | void | 
|---|
| 1137 | pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, int num, int gen) | 
|---|
| 1138 | { | 
|---|
| 1139 | unsigned char key[32]; | 
|---|
| 1140 | int len; | 
|---|
| 1141 |  | 
|---|
| 1142 | len = pdf_compute_object_key(crypt, &crypt->strf, num, gen, key, 32); | 
|---|
| 1143 |  | 
|---|
| 1144 | pdf_crypt_obj_imp(ctx, crypt, obj, key, len); | 
|---|
| 1145 | } | 
|---|
| 1146 |  | 
|---|
| 1147 | /* | 
|---|
| 1148 | * PDF 1.7 algorithm 3.1 and ExtensionLevel 3 algorithm 3.1a | 
|---|
| 1149 | * | 
|---|
| 1150 | * Create filter suitable for de/encrypting a stream. | 
|---|
| 1151 | */ | 
|---|
| 1152 | static fz_stream * | 
|---|
| 1153 | pdf_open_crypt_imp(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, pdf_crypt_filter *stmf, int num, int gen) | 
|---|
| 1154 | { | 
|---|
| 1155 | unsigned char key[32]; | 
|---|
| 1156 | int len; | 
|---|
| 1157 |  | 
|---|
| 1158 | len = pdf_compute_object_key(crypt, stmf, num, gen, key, 32); | 
|---|
| 1159 |  | 
|---|
| 1160 | if (stmf->method == PDF_CRYPT_RC4) | 
|---|
| 1161 | return fz_open_arc4(ctx, chain, key, len); | 
|---|
| 1162 |  | 
|---|
| 1163 | if (stmf->method == PDF_CRYPT_AESV2 || stmf->method == PDF_CRYPT_AESV3) | 
|---|
| 1164 | return fz_open_aesd(ctx, chain, key, len); | 
|---|
| 1165 |  | 
|---|
| 1166 | return fz_keep_stream(ctx, chain); | 
|---|
| 1167 | } | 
|---|
| 1168 |  | 
|---|
| 1169 | fz_stream * | 
|---|
| 1170 | pdf_open_crypt(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, int num, int gen) | 
|---|
| 1171 | { | 
|---|
| 1172 | return pdf_open_crypt_imp(ctx, chain, crypt, &crypt->stmf, num, gen); | 
|---|
| 1173 | } | 
|---|
| 1174 |  | 
|---|
| 1175 | fz_stream * | 
|---|
| 1176 | pdf_open_crypt_with_filter(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, pdf_obj *name, int num, int gen) | 
|---|
| 1177 | { | 
|---|
| 1178 | if (!pdf_name_eq(ctx, name, PDF_NAME(Identity))) | 
|---|
| 1179 | { | 
|---|
| 1180 | pdf_crypt_filter cf; | 
|---|
| 1181 | pdf_parse_crypt_filter(ctx, &cf, crypt, name); | 
|---|
| 1182 | return pdf_open_crypt_imp(ctx, chain, crypt, &cf, num, gen); | 
|---|
| 1183 | } | 
|---|
| 1184 | return fz_keep_stream(ctx, chain); | 
|---|
| 1185 | } | 
|---|
| 1186 |  | 
|---|
| 1187 | void | 
|---|
| 1188 | pdf_print_crypt(fz_context *ctx, fz_output *out, pdf_crypt *crypt) | 
|---|
| 1189 | { | 
|---|
| 1190 | int i; | 
|---|
| 1191 |  | 
|---|
| 1192 | fz_write_printf(ctx, out, "crypt {\n"); | 
|---|
| 1193 |  | 
|---|
| 1194 | fz_write_printf(ctx, out, "\tv=%d length=%d\n", crypt->v, crypt->length); | 
|---|
| 1195 | fz_write_printf(ctx, out, "\tstmf method=%d length=%d\n", crypt->stmf.method, crypt->stmf.length); | 
|---|
| 1196 | fz_write_printf(ctx, out, "\tstrf method=%d length=%d\n", crypt->strf.method, crypt->strf.length); | 
|---|
| 1197 | fz_write_printf(ctx, out, "\tr=%d\n", crypt->r); | 
|---|
| 1198 |  | 
|---|
| 1199 | fz_write_printf(ctx, out, "\to=<"); | 
|---|
| 1200 | for (i = 0; i < 32; i++) | 
|---|
| 1201 | fz_write_printf(ctx, out, "%02X", crypt->o[i]); | 
|---|
| 1202 | fz_write_printf(ctx, out, ">\n"); | 
|---|
| 1203 |  | 
|---|
| 1204 | fz_write_printf(ctx, out, "\tu=<"); | 
|---|
| 1205 | for (i = 0; i < 32; i++) | 
|---|
| 1206 | fz_write_printf(ctx, out, "%02X", crypt->u[i]); | 
|---|
| 1207 | fz_write_printf(ctx, out, ">\n"); | 
|---|
| 1208 |  | 
|---|
| 1209 | fz_write_printf(ctx, out, "}\n"); | 
|---|
| 1210 | } | 
|---|
| 1211 |  | 
|---|
| 1212 | void pdf_encrypt_data(fz_context *ctx, pdf_crypt *crypt, int num, int gen, void (*write_data)(fz_context *ctx, void *, const unsigned char *, int), void *arg, const unsigned char *s, int n) | 
|---|
| 1213 | { | 
|---|
| 1214 | unsigned char buffer[256]; | 
|---|
| 1215 | unsigned char key[32]; | 
|---|
| 1216 | int keylen; | 
|---|
| 1217 |  | 
|---|
| 1218 | if (crypt == NULL) | 
|---|
| 1219 | { | 
|---|
| 1220 | write_data(ctx, arg, s, n); | 
|---|
| 1221 | return; | 
|---|
| 1222 | } | 
|---|
| 1223 |  | 
|---|
| 1224 | keylen = pdf_compute_object_key(crypt, &crypt->strf, num, gen, key, 32); | 
|---|
| 1225 |  | 
|---|
| 1226 | if (crypt->strf.method == PDF_CRYPT_RC4) | 
|---|
| 1227 | { | 
|---|
| 1228 | fz_arc4 arc4; | 
|---|
| 1229 | fz_arc4_init(&arc4, key, keylen); | 
|---|
| 1230 | while (n > 0) | 
|---|
| 1231 | { | 
|---|
| 1232 | int len = n; | 
|---|
| 1233 | if (len > sizeof(buffer)) | 
|---|
| 1234 | len = sizeof(buffer); | 
|---|
| 1235 | fz_arc4_encrypt(&arc4, buffer, s, len); | 
|---|
| 1236 | write_data(ctx, arg, buffer, len); | 
|---|
| 1237 | s += len; | 
|---|
| 1238 | n -= len; | 
|---|
| 1239 | } | 
|---|
| 1240 | return; | 
|---|
| 1241 | } | 
|---|
| 1242 |  | 
|---|
| 1243 | if (crypt->strf.method == PDF_CRYPT_AESV2 || crypt->strf.method == PDF_CRYPT_AESV3) | 
|---|
| 1244 | { | 
|---|
| 1245 | fz_aes aes; | 
|---|
| 1246 | unsigned char iv[16]; | 
|---|
| 1247 |  | 
|---|
| 1248 | /* Empty strings can be represented by empty strings */ | 
|---|
| 1249 | if (n == 0) | 
|---|
| 1250 | return; | 
|---|
| 1251 |  | 
|---|
| 1252 | if (fz_aes_setkey_enc(&aes, key, keylen * 8)) | 
|---|
| 1253 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", keylen * 8); | 
|---|
| 1254 |  | 
|---|
| 1255 | fz_memrnd(ctx, iv, 16); | 
|---|
| 1256 | write_data(ctx, arg, iv, 16); | 
|---|
| 1257 |  | 
|---|
| 1258 | while (n > 0) | 
|---|
| 1259 | { | 
|---|
| 1260 | int len = n; | 
|---|
| 1261 | if (len > 16) | 
|---|
| 1262 | len = 16; | 
|---|
| 1263 | memcpy(buffer, s, len); | 
|---|
| 1264 | if (len != 16) | 
|---|
| 1265 | memset(&buffer[len], 16-len, 16-len); | 
|---|
| 1266 | fz_aes_crypt_cbc(&aes, FZ_AES_ENCRYPT, 16, iv, buffer, buffer+16); | 
|---|
| 1267 | write_data(ctx, arg, buffer+16, 16); | 
|---|
| 1268 | s += 16; | 
|---|
| 1269 | n -= 16; | 
|---|
| 1270 | } | 
|---|
| 1271 | if (n == 0) { | 
|---|
| 1272 | memset(buffer, 16, 16); | 
|---|
| 1273 | fz_aes_crypt_cbc(&aes, FZ_AES_ENCRYPT, 16, iv, buffer, buffer+16); | 
|---|
| 1274 | write_data(ctx, arg, buffer+16, 16); | 
|---|
| 1275 | } | 
|---|
| 1276 | return; | 
|---|
| 1277 | } | 
|---|
| 1278 |  | 
|---|
| 1279 | /* Should never happen, but... */ | 
|---|
| 1280 | write_data(ctx, arg, s, n); | 
|---|
| 1281 | } | 
|---|
| 1282 |  | 
|---|
| 1283 | int pdf_encrypted_len(fz_context *ctx, pdf_crypt *crypt, int num, int gen, int len) | 
|---|
| 1284 | { | 
|---|
| 1285 | if (crypt == NULL) | 
|---|
| 1286 | return len; | 
|---|
| 1287 |  | 
|---|
| 1288 | if (crypt->strf.method == PDF_CRYPT_AESV2 || crypt->strf.method == PDF_CRYPT_AESV3) | 
|---|
| 1289 | { | 
|---|
| 1290 | len += 16; /* 16 for IV */ | 
|---|
| 1291 | if ((len & 15) == 0) | 
|---|
| 1292 | len += 16; /* Another 16 if our last block is full anyway */ | 
|---|
| 1293 | len = (len + 15) & ~15; /* And pad to the block */ | 
|---|
| 1294 | } | 
|---|
| 1295 |  | 
|---|
| 1296 | return len; | 
|---|
| 1297 | } | 
|---|
| 1298 |  | 
|---|
| 1299 | /* PDF 2.0 algorithm 8 */ | 
|---|
| 1300 | static void | 
|---|
| 1301 | pdf_compute_user_password_r6(fz_context *ctx, pdf_crypt *crypt, unsigned char *password, size_t pwlen, unsigned char *outputpw, unsigned char *outputencryption) | 
|---|
| 1302 | { | 
|---|
| 1303 | unsigned char validationsalt[8]; | 
|---|
| 1304 | unsigned char keysalt[8]; | 
|---|
| 1305 | unsigned char hash[32]; | 
|---|
| 1306 | unsigned char iv[16]; | 
|---|
| 1307 | fz_aes aes; | 
|---|
| 1308 |  | 
|---|
| 1309 | /* Step a) - Generate random salts. */ | 
|---|
| 1310 | fz_memrnd(ctx, validationsalt, nelem(validationsalt)); | 
|---|
| 1311 | fz_memrnd(ctx, keysalt, nelem(keysalt)); | 
|---|
| 1312 |  | 
|---|
| 1313 | /* Step a) - Compute 32 byte hash given password and validation salt. */ | 
|---|
| 1314 | pdf_compute_hardened_hash_r6(ctx, password, pwlen, validationsalt, NULL, outputpw); | 
|---|
| 1315 | memcpy(outputpw + 32, validationsalt, nelem(validationsalt)); | 
|---|
| 1316 | memcpy(outputpw + 40, keysalt, nelem(keysalt)); | 
|---|
| 1317 |  | 
|---|
| 1318 | /* Step b) - Compute 32 byte hash given password and user salt. */ | 
|---|
| 1319 | pdf_compute_hardened_hash_r6(ctx, password, pwlen, keysalt, NULL, hash); | 
|---|
| 1320 |  | 
|---|
| 1321 | /* Step b) - Use hash as AES-key when encrypting the file encryption key. */ | 
|---|
| 1322 | memset(iv, 0, sizeof(iv)); | 
|---|
| 1323 | if (fz_aes_setkey_enc(&aes, hash, 256)) | 
|---|
| 1324 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=256)"); | 
|---|
| 1325 | fz_aes_crypt_cbc(&aes, FZ_AES_ENCRYPT, 32, iv, crypt->key, outputencryption); | 
|---|
| 1326 | } | 
|---|
| 1327 |  | 
|---|
| 1328 | /* PDF 2.0 algorithm 9 */ | 
|---|
| 1329 | static void | 
|---|
| 1330 | pdf_compute_owner_password_r6(fz_context *ctx, pdf_crypt *crypt, unsigned char *password, size_t pwlen, unsigned char *outputpw, unsigned char *outputencryption) | 
|---|
| 1331 | { | 
|---|
| 1332 | unsigned char validationsalt[8]; | 
|---|
| 1333 | unsigned char keysalt[8]; | 
|---|
| 1334 | unsigned char hash[32]; | 
|---|
| 1335 | unsigned char iv[16]; | 
|---|
| 1336 | fz_aes aes; | 
|---|
| 1337 |  | 
|---|
| 1338 | /* Step a) - Generate random salts. */ | 
|---|
| 1339 | fz_memrnd(ctx, validationsalt, nelem(validationsalt)); | 
|---|
| 1340 | fz_memrnd(ctx, keysalt, nelem(keysalt)); | 
|---|
| 1341 |  | 
|---|
| 1342 | /* Step a) - Compute 32 byte hash given owner password, validation salt and user password. */ | 
|---|
| 1343 | pdf_compute_hardened_hash_r6(ctx, password, pwlen, validationsalt, crypt->u, outputpw); | 
|---|
| 1344 | memcpy(outputpw + 32, validationsalt, nelem(validationsalt)); | 
|---|
| 1345 | memcpy(outputpw + 40, keysalt, nelem(keysalt)); | 
|---|
| 1346 |  | 
|---|
| 1347 | /* Step b) - Compute 32 byte hash given owner password, user salt and user password. */ | 
|---|
| 1348 | pdf_compute_hardened_hash_r6(ctx, password, pwlen, keysalt, crypt->u, hash); | 
|---|
| 1349 |  | 
|---|
| 1350 | /* Step b) - Use hash as AES-key when encrypting the file encryption key. */ | 
|---|
| 1351 | memset(iv, 0, sizeof(iv)); | 
|---|
| 1352 | if (fz_aes_setkey_enc(&aes, hash, 256)) | 
|---|
| 1353 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=256)"); | 
|---|
| 1354 | fz_aes_crypt_cbc(&aes, FZ_AES_ENCRYPT, 32, iv, crypt->key, outputencryption); | 
|---|
| 1355 | } | 
|---|
| 1356 |  | 
|---|
| 1357 | /* PDF 2.0 algorithm 10 */ | 
|---|
| 1358 | static void | 
|---|
| 1359 | pdf_compute_permissions_r6(fz_context *ctx, pdf_crypt *crypt, unsigned char *output) | 
|---|
| 1360 | { | 
|---|
| 1361 | unsigned char buf[16]; | 
|---|
| 1362 | unsigned char iv[16]; | 
|---|
| 1363 | fz_aes aes; | 
|---|
| 1364 |  | 
|---|
| 1365 | /* Steps a) and b) - Extend permissions field and put into lower order bytes. */ | 
|---|
| 1366 | memcpy(buf, (unsigned char *) &crypt->p, 4); | 
|---|
| 1367 | memset(&buf[4], 0xff, 4); | 
|---|
| 1368 |  | 
|---|
| 1369 | /* Step c) - Encode EncryptMetadata as T/F. */ | 
|---|
| 1370 | buf[8] = crypt->encrypt_metadata ? 'T' : 'F'; | 
|---|
| 1371 |  | 
|---|
| 1372 | /* Step d) - Encode ASCII characters "adb". */ | 
|---|
| 1373 | buf[9] = 'a'; | 
|---|
| 1374 | buf[10] = 'd'; | 
|---|
| 1375 | buf[11] = 'b'; | 
|---|
| 1376 |  | 
|---|
| 1377 | /* Step e) - Encode 4 random bytes. */ | 
|---|
| 1378 | fz_memrnd(ctx, &buf[12], 4); | 
|---|
| 1379 |  | 
|---|
| 1380 | /* Step f) - Use file encryption key as AES-key when encrypting buffer. */ | 
|---|
| 1381 | memset(iv, 0, sizeof(iv)); | 
|---|
| 1382 | if (fz_aes_setkey_enc(&aes, crypt->key, 256)) | 
|---|
| 1383 | fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=256)"); | 
|---|
| 1384 | fz_aes_crypt_cbc(&aes, FZ_AES_ENCRYPT, 16, iv, buf, output); | 
|---|
| 1385 | } | 
|---|
| 1386 |  | 
|---|
| 1387 | pdf_crypt * | 
|---|
| 1388 | pdf_new_encrypt(fz_context *ctx, const char *opwd_utf8, const char *upwd_utf8, pdf_obj *id, int permissions, int algorithm) | 
|---|
| 1389 | { | 
|---|
| 1390 | pdf_crypt *crypt; | 
|---|
| 1391 | int v, r, method, length; | 
|---|
| 1392 | unsigned char opwd[2048]; | 
|---|
| 1393 | unsigned char upwd[2048]; | 
|---|
| 1394 | size_t opwdlen, upwdlen; | 
|---|
| 1395 |  | 
|---|
| 1396 | crypt = fz_malloc_struct(ctx, pdf_crypt); | 
|---|
| 1397 |  | 
|---|
| 1398 | /* Extract file identifier string */ | 
|---|
| 1399 |  | 
|---|
| 1400 | if (pdf_is_string(ctx, id)) | 
|---|
| 1401 | crypt->id = pdf_keep_obj(ctx, id); | 
|---|
| 1402 | else | 
|---|
| 1403 | fz_warn(ctx, "missing file identifier, may not be able to do decryption"); | 
|---|
| 1404 |  | 
|---|
| 1405 | switch (algorithm) | 
|---|
| 1406 | { | 
|---|
| 1407 | case PDF_ENCRYPT_RC4_40: | 
|---|
| 1408 | v = 1; r = 2; method = PDF_CRYPT_RC4; length = 40; break; | 
|---|
| 1409 | case PDF_ENCRYPT_RC4_128: | 
|---|
| 1410 | v = 2; r = 3; method = PDF_CRYPT_RC4; length = 128; break; | 
|---|
| 1411 | case PDF_ENCRYPT_AES_128: | 
|---|
| 1412 | v = 4; r = 4; method = PDF_CRYPT_AESV2; length = 128; break; | 
|---|
| 1413 | case PDF_ENCRYPT_AES_256: | 
|---|
| 1414 | v = 5; r = 6; method = PDF_CRYPT_AESV3; length = 256; break; | 
|---|
| 1415 | default: | 
|---|
| 1416 | fz_throw(ctx, FZ_ERROR_GENERIC, "invalid encryption method"); | 
|---|
| 1417 | } | 
|---|
| 1418 |  | 
|---|
| 1419 | crypt->v = v; | 
|---|
| 1420 | crypt->r = r; | 
|---|
| 1421 | crypt->length = length; | 
|---|
| 1422 | crypt->cf = NULL; | 
|---|
| 1423 | crypt->stmf.method = method; | 
|---|
| 1424 | crypt->stmf.length = length; | 
|---|
| 1425 | crypt->strf.method = method; | 
|---|
| 1426 | crypt->strf.length = length; | 
|---|
| 1427 | crypt->encrypt_metadata = 1; | 
|---|
| 1428 | crypt->p = (permissions & 0xf3c) | 0xfffff0c0; | 
|---|
| 1429 | memset(crypt->o, 0, sizeof (crypt->o)); | 
|---|
| 1430 | memset(crypt->u, 0, sizeof (crypt->u)); | 
|---|
| 1431 | memset(crypt->oe, 0, sizeof (crypt->oe)); | 
|---|
| 1432 | memset(crypt->ue, 0, sizeof (crypt->ue)); | 
|---|
| 1433 |  | 
|---|
| 1434 | if (crypt->r <= 4) | 
|---|
| 1435 | { | 
|---|
| 1436 | pdf_docenc_from_utf8((char *) opwd, opwd_utf8, sizeof opwd); | 
|---|
| 1437 | pdf_docenc_from_utf8((char *) upwd, upwd_utf8, sizeof upwd); | 
|---|
| 1438 | } | 
|---|
| 1439 | else | 
|---|
| 1440 | { | 
|---|
| 1441 | pdf_saslprep_from_utf8((char *) opwd, opwd_utf8, sizeof opwd); | 
|---|
| 1442 | pdf_saslprep_from_utf8((char *) upwd, upwd_utf8, sizeof upwd); | 
|---|
| 1443 | } | 
|---|
| 1444 |  | 
|---|
| 1445 | opwdlen = strlen((char *) opwd); | 
|---|
| 1446 | upwdlen = strlen((char *) upwd); | 
|---|
| 1447 |  | 
|---|
| 1448 | if (crypt->r <= 4) | 
|---|
| 1449 | { | 
|---|
| 1450 | pdf_compute_owner_password(ctx, crypt, opwd, opwdlen, upwd, upwdlen, crypt->o); | 
|---|
| 1451 | pdf_compute_user_password(ctx, crypt, upwd, upwdlen, crypt->u); | 
|---|
| 1452 | } | 
|---|
| 1453 | else if (crypt->r == 6) | 
|---|
| 1454 | { | 
|---|
| 1455 | /* 7.6.4.4.1 states that the file encryption key are 256 random bits. */ | 
|---|
| 1456 | fz_memrnd(ctx, crypt->key, nelem(crypt->key)); | 
|---|
| 1457 |  | 
|---|
| 1458 | pdf_compute_user_password_r6(ctx, crypt, upwd, upwdlen, crypt->u, crypt->ue); | 
|---|
| 1459 | pdf_compute_owner_password_r6(ctx, crypt, opwd, opwdlen, crypt->o, crypt->oe); | 
|---|
| 1460 | pdf_compute_permissions_r6(ctx, crypt, crypt->perms); | 
|---|
| 1461 | } | 
|---|
| 1462 |  | 
|---|
| 1463 | return crypt; | 
|---|
| 1464 | } | 
|---|
| 1465 |  | 
|---|