1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/include/fpdfapi/fpdf_parser.h"
8
9 #include <time.h>
10
11 #include "core/include/fdrm/fx_crypt.h"
12
13 const uint8_t defpasscode[32] = {
14 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e,
15 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68,
16 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a};
CalcEncryptKey(CPDF_Dictionary * pEncrypt,const uint8_t * password,FX_DWORD pass_size,uint8_t * key,int keylen,FX_BOOL bIgnoreMeta,CPDF_Array * pIdArray)17 void CalcEncryptKey(CPDF_Dictionary* pEncrypt,
18 const uint8_t* password,
19 FX_DWORD pass_size,
20 uint8_t* key,
21 int keylen,
22 FX_BOOL bIgnoreMeta,
23 CPDF_Array* pIdArray) {
24 int revision = pEncrypt->GetInteger("R");
25 uint8_t passcode[32];
26 for (FX_DWORD i = 0; i < 32; i++) {
27 passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size];
28 }
29 uint8_t md5[100];
30 CRYPT_MD5Start(md5);
31 CRYPT_MD5Update(md5, passcode, 32);
32 CFX_ByteString okey = pEncrypt->GetString("O");
33 CRYPT_MD5Update(md5, (uint8_t*)okey.c_str(), okey.GetLength());
34 FX_DWORD perm = pEncrypt->GetInteger("P");
35 CRYPT_MD5Update(md5, (uint8_t*)&perm, 4);
36 if (pIdArray) {
37 CFX_ByteString id = pIdArray->GetString(0);
38 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
39 }
40 if (!bIgnoreMeta && revision >= 3 &&
41 !pEncrypt->GetInteger("EncryptMetadata", 1)) {
42 FX_DWORD tag = (FX_DWORD)-1;
43 CRYPT_MD5Update(md5, (uint8_t*)&tag, 4);
44 }
45 uint8_t digest[16];
46 CRYPT_MD5Finish(md5, digest);
47 FX_DWORD copy_len = keylen;
48 if (copy_len > sizeof(digest)) {
49 copy_len = sizeof(digest);
50 }
51 if (revision >= 3) {
52 for (int i = 0; i < 50; i++) {
53 CRYPT_MD5Generate(digest, copy_len, digest);
54 }
55 }
56 FXSYS_memset(key, 0, keylen);
57 FXSYS_memcpy(key, digest, copy_len);
58 }
CreateCryptoHandler()59 CPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler() {
60 return new CPDF_StandardCryptoHandler;
61 }
62 typedef struct _PDF_CRYPTOITEM {
63 int32_t m_Cipher;
64 int32_t m_KeyLen;
65 FX_BOOL m_bChecked;
66 CPDF_StandardCryptoHandler* m_pCryptoHandler;
67 } PDF_CRYPTOITEM;
CPDF_StandardSecurityHandler()68 CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler() {
69 m_Version = 0;
70 m_Revision = 0;
71 m_pParser = NULL;
72 m_pEncryptDict = NULL;
73 m_bOwner = FALSE;
74 m_Permissions = 0;
75 m_Cipher = FXCIPHER_NONE;
76 m_KeyLen = 0;
77 }
~CPDF_StandardSecurityHandler()78 CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler() {}
OnInit(CPDF_Parser * pParser,CPDF_Dictionary * pEncryptDict)79 FX_BOOL CPDF_StandardSecurityHandler::OnInit(CPDF_Parser* pParser,
80 CPDF_Dictionary* pEncryptDict) {
81 m_pParser = pParser;
82 if (!LoadDict(pEncryptDict)) {
83 return FALSE;
84 }
85 if (m_Cipher == FXCIPHER_NONE) {
86 return TRUE;
87 }
88 return CheckSecurity(m_KeyLen);
89 }
CheckSecurity(int32_t key_len)90 FX_BOOL CPDF_StandardSecurityHandler::CheckSecurity(int32_t key_len) {
91 CFX_ByteString password = m_pParser->GetPassword();
92 if (CheckPassword(password, password.GetLength(), TRUE, m_EncryptKey,
93 key_len)) {
94 if (password.IsEmpty()) {
95 if (!CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey,
96 key_len)) {
97 return FALSE;
98 }
99 }
100 m_bOwner = TRUE;
101 return TRUE;
102 }
103 return CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey,
104 key_len);
105 }
GetPermissions()106 FX_DWORD CPDF_StandardSecurityHandler::GetPermissions() {
107 return m_Permissions;
108 }
_LoadCryptInfo(CPDF_Dictionary * pEncryptDict,const CFX_ByteStringC & name,int & cipher,int & keylen)109 static FX_BOOL _LoadCryptInfo(CPDF_Dictionary* pEncryptDict,
110 const CFX_ByteStringC& name,
111 int& cipher,
112 int& keylen) {
113 int Version = pEncryptDict->GetInteger("V");
114 cipher = FXCIPHER_RC4;
115 keylen = 0;
116 if (Version >= 4) {
117 CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDict("CF");
118 if (!pCryptFilters) {
119 return FALSE;
120 }
121 if (name == "Identity") {
122 cipher = FXCIPHER_NONE;
123 } else {
124 CPDF_Dictionary* pDefFilter = pCryptFilters->GetDict(name);
125 if (!pDefFilter) {
126 return FALSE;
127 }
128 int nKeyBits = 0;
129 if (Version == 4) {
130 nKeyBits = pDefFilter->GetInteger("Length", 0);
131 if (nKeyBits == 0) {
132 nKeyBits = pEncryptDict->GetInteger("Length", 128);
133 }
134 } else {
135 nKeyBits = pEncryptDict->GetInteger("Length", 256);
136 }
137 if (nKeyBits < 40) {
138 nKeyBits *= 8;
139 }
140 keylen = nKeyBits / 8;
141 CFX_ByteString cipher_name = pDefFilter->GetString("CFM");
142 if (cipher_name == "AESV2" || cipher_name == "AESV3") {
143 cipher = FXCIPHER_AES;
144 }
145 }
146 } else {
147 keylen = Version > 1 ? pEncryptDict->GetInteger("Length", 40) / 8 : 5;
148 }
149 if (keylen > 32 || keylen < 0) {
150 return FALSE;
151 }
152 return TRUE;
153 }
LoadDict(CPDF_Dictionary * pEncryptDict)154 FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) {
155 m_pEncryptDict = pEncryptDict;
156 m_bOwner = FALSE;
157 m_Version = pEncryptDict->GetInteger("V");
158 m_Revision = pEncryptDict->GetInteger("R");
159 m_Permissions = pEncryptDict->GetInteger("P", -1);
160 if (m_Version < 4) {
161 return _LoadCryptInfo(pEncryptDict, CFX_ByteString(), m_Cipher, m_KeyLen);
162 }
163 CFX_ByteString stmf_name = pEncryptDict->GetString("StmF");
164 CFX_ByteString strf_name = pEncryptDict->GetString("StrF");
165 if (stmf_name != strf_name) {
166 return FALSE;
167 }
168 if (!_LoadCryptInfo(pEncryptDict, strf_name, m_Cipher, m_KeyLen)) {
169 return FALSE;
170 }
171 return TRUE;
172 }
LoadDict(CPDF_Dictionary * pEncryptDict,FX_DWORD type,int & cipher,int & key_len)173 FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict,
174 FX_DWORD type,
175 int& cipher,
176 int& key_len) {
177 m_pEncryptDict = pEncryptDict;
178 m_bOwner = FALSE;
179 m_Version = pEncryptDict->GetInteger("V");
180 m_Revision = pEncryptDict->GetInteger("R");
181 m_Permissions = pEncryptDict->GetInteger("P", -1);
182 CFX_ByteString strf_name, stmf_name;
183 if (m_Version >= 4) {
184 stmf_name = pEncryptDict->GetString("StmF");
185 strf_name = pEncryptDict->GetString("StrF");
186 if (stmf_name != strf_name) {
187 return FALSE;
188 }
189 }
190 if (!_LoadCryptInfo(pEncryptDict, strf_name, cipher, key_len)) {
191 return FALSE;
192 }
193 m_Cipher = cipher;
194 m_KeyLen = key_len;
195 return TRUE;
196 return TRUE;
197 }
GetCryptInfo(int & cipher,const uint8_t * & buffer,int & keylen)198 FX_BOOL CPDF_StandardSecurityHandler::GetCryptInfo(int& cipher,
199 const uint8_t*& buffer,
200 int& keylen) {
201 cipher = m_Cipher;
202 buffer = m_EncryptKey;
203 keylen = m_KeyLen;
204 return TRUE;
205 }
206 #define FX_GET_32WORD(n, b, i) \
207 { \
208 (n) = (FX_DWORD)( \
209 ((uint64_t)(b)[(i)] << 24) | ((uint64_t)(b)[(i) + 1] << 16) | \
210 ((uint64_t)(b)[(i) + 2] << 8) | ((uint64_t)(b)[(i) + 3])); \
211 }
BigOrder64BitsMod3(uint8_t * data)212 int BigOrder64BitsMod3(uint8_t* data) {
213 uint64_t ret = 0;
214 for (int i = 0; i < 4; ++i) {
215 FX_DWORD value;
216 FX_GET_32WORD(value, data, 4 * i);
217 ret <<= 32;
218 ret |= value;
219 ret %= 3;
220 }
221 return (int)ret;
222 }
Revision6_Hash(const uint8_t * password,FX_DWORD size,const uint8_t * salt,const uint8_t * vector,uint8_t * hash)223 void Revision6_Hash(const uint8_t* password,
224 FX_DWORD size,
225 const uint8_t* salt,
226 const uint8_t* vector,
227 uint8_t* hash) {
228 int iBlockSize = 32;
229 uint8_t sha[128];
230 CRYPT_SHA256Start(sha);
231 CRYPT_SHA256Update(sha, password, size);
232 CRYPT_SHA256Update(sha, salt, 8);
233 if (vector) {
234 CRYPT_SHA256Update(sha, vector, 48);
235 }
236 uint8_t digest[32];
237 CRYPT_SHA256Finish(sha, digest);
238 CFX_ByteTextBuf buf;
239 uint8_t* input = digest;
240 uint8_t* key = input;
241 uint8_t* iv = input + 16;
242 uint8_t* E = buf.GetBuffer();
243 int iBufLen = buf.GetLength();
244 CFX_ByteTextBuf interDigest;
245 int i = 0;
246 uint8_t* aes = FX_Alloc(uint8_t, 2048);
247 while (i < 64 || i < E[iBufLen - 1] + 32) {
248 int iRoundSize = size + iBlockSize;
249 if (vector) {
250 iRoundSize += 48;
251 }
252 iBufLen = iRoundSize * 64;
253 buf.EstimateSize(iBufLen);
254 E = buf.GetBuffer();
255 CFX_ByteTextBuf content;
256 for (int j = 0; j < 64; ++j) {
257 content.AppendBlock(password, size);
258 content.AppendBlock(input, iBlockSize);
259 if (vector) {
260 content.AppendBlock(vector, 48);
261 }
262 }
263 CRYPT_AESSetKey(aes, 16, key, 16, TRUE);
264 CRYPT_AESSetIV(aes, iv);
265 CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen);
266 int iHash = 0;
267 switch (BigOrder64BitsMod3(E)) {
268 case 0:
269 iHash = 0;
270 iBlockSize = 32;
271 break;
272 case 1:
273 iHash = 1;
274 iBlockSize = 48;
275 break;
276 default:
277 iHash = 2;
278 iBlockSize = 64;
279 break;
280 }
281 interDigest.EstimateSize(iBlockSize);
282 input = interDigest.GetBuffer();
283 if (iHash == 0) {
284 CRYPT_SHA256Generate(E, iBufLen, input);
285 } else if (iHash == 1) {
286 CRYPT_SHA384Generate(E, iBufLen, input);
287 } else if (iHash == 2) {
288 CRYPT_SHA512Generate(E, iBufLen, input);
289 }
290 key = input;
291 iv = input + 16;
292 ++i;
293 }
294 FX_Free(aes);
295 if (hash) {
296 FXSYS_memcpy(hash, input, 32);
297 }
298 }
AES256_CheckPassword(const uint8_t * password,FX_DWORD size,FX_BOOL bOwner,uint8_t * key)299 FX_BOOL CPDF_StandardSecurityHandler::AES256_CheckPassword(
300 const uint8_t* password,
301 FX_DWORD size,
302 FX_BOOL bOwner,
303 uint8_t* key) {
304 CFX_ByteString okey =
305 m_pEncryptDict ? m_pEncryptDict->GetString("O") : CFX_ByteString();
306 if (okey.GetLength() < 48) {
307 return FALSE;
308 }
309 CFX_ByteString ukey =
310 m_pEncryptDict ? m_pEncryptDict->GetString("U") : CFX_ByteString();
311 if (ukey.GetLength() < 48) {
312 return FALSE;
313 }
314 const uint8_t* pkey = bOwner ? (const uint8_t*)okey : (const uint8_t*)ukey;
315 uint8_t sha[128];
316 uint8_t digest[32];
317 if (m_Revision >= 6) {
318 Revision6_Hash(password, size, (const uint8_t*)pkey + 32,
319 (bOwner ? (const uint8_t*)ukey : NULL), digest);
320 } else {
321 CRYPT_SHA256Start(sha);
322 CRYPT_SHA256Update(sha, password, size);
323 CRYPT_SHA256Update(sha, pkey + 32, 8);
324 if (bOwner) {
325 CRYPT_SHA256Update(sha, ukey, 48);
326 }
327 CRYPT_SHA256Finish(sha, digest);
328 }
329 if (FXSYS_memcmp(digest, pkey, 32) != 0) {
330 return FALSE;
331 }
332 if (!key) {
333 return TRUE;
334 }
335 if (m_Revision >= 6) {
336 Revision6_Hash(password, size, (const uint8_t*)pkey + 40,
337 (bOwner ? (const uint8_t*)ukey : NULL), digest);
338 } else {
339 CRYPT_SHA256Start(sha);
340 CRYPT_SHA256Update(sha, password, size);
341 CRYPT_SHA256Update(sha, pkey + 40, 8);
342 if (bOwner) {
343 CRYPT_SHA256Update(sha, ukey, 48);
344 }
345 CRYPT_SHA256Finish(sha, digest);
346 }
347 CFX_ByteString ekey = m_pEncryptDict
348 ? m_pEncryptDict->GetString(bOwner ? "OE" : "UE")
349 : CFX_ByteString();
350 if (ekey.GetLength() < 32) {
351 return FALSE;
352 }
353 uint8_t* aes = FX_Alloc(uint8_t, 2048);
354 CRYPT_AESSetKey(aes, 16, digest, 32, FALSE);
355 uint8_t iv[16];
356 FXSYS_memset(iv, 0, 16);
357 CRYPT_AESSetIV(aes, iv);
358 CRYPT_AESDecrypt(aes, key, ekey, 32);
359 CRYPT_AESSetKey(aes, 16, key, 32, FALSE);
360 CRYPT_AESSetIV(aes, iv);
361 CFX_ByteString perms = m_pEncryptDict->GetString("Perms");
362 if (perms.IsEmpty()) {
363 return FALSE;
364 }
365 uint8_t perms_buf[16];
366 FXSYS_memset(perms_buf, 0, sizeof(perms_buf));
367 FX_DWORD copy_len = sizeof(perms_buf);
368 if (copy_len > (FX_DWORD)perms.GetLength()) {
369 copy_len = perms.GetLength();
370 }
371 FXSYS_memcpy(perms_buf, (const uint8_t*)perms, copy_len);
372 uint8_t buf[16];
373 CRYPT_AESDecrypt(aes, buf, perms_buf, 16);
374 FX_Free(aes);
375 if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') {
376 return FALSE;
377 }
378 if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) {
379 return FALSE;
380 }
381 if ((buf[8] == 'T' && !IsMetadataEncrypted()) ||
382 (buf[8] == 'F' && IsMetadataEncrypted())) {
383 return FALSE;
384 }
385 return TRUE;
386 }
CheckPassword(const uint8_t * password,FX_DWORD pass_size,FX_BOOL bOwner,uint8_t * key)387 int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password,
388 FX_DWORD pass_size,
389 FX_BOOL bOwner,
390 uint8_t* key) {
391 return CheckPassword(password, pass_size, bOwner, key, m_KeyLen);
392 }
CheckPassword(const uint8_t * password,FX_DWORD size,FX_BOOL bOwner,uint8_t * key,int32_t key_len)393 int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password,
394 FX_DWORD size,
395 FX_BOOL bOwner,
396 uint8_t* key,
397 int32_t key_len) {
398 if (m_Revision >= 5) {
399 return AES256_CheckPassword(password, size, bOwner, key);
400 }
401 uint8_t keybuf[32];
402 if (!key) {
403 key = keybuf;
404 }
405 if (bOwner) {
406 return CheckOwnerPassword(password, size, key, key_len);
407 }
408 return CheckUserPassword(password, size, FALSE, key, key_len) ||
409 CheckUserPassword(password, size, TRUE, key, key_len);
410 }
CheckUserPassword(const uint8_t * password,FX_DWORD pass_size,FX_BOOL bIgnoreEncryptMeta,uint8_t * key,int32_t key_len)411 FX_BOOL CPDF_StandardSecurityHandler::CheckUserPassword(
412 const uint8_t* password,
413 FX_DWORD pass_size,
414 FX_BOOL bIgnoreEncryptMeta,
415 uint8_t* key,
416 int32_t key_len) {
417 CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len,
418 bIgnoreEncryptMeta, m_pParser->GetIDArray());
419 CFX_ByteString ukey =
420 m_pEncryptDict ? m_pEncryptDict->GetString("U") : CFX_ByteString();
421 if (ukey.GetLength() < 16) {
422 return FALSE;
423 }
424 uint8_t ukeybuf[32];
425 if (m_Revision == 2) {
426 FXSYS_memcpy(ukeybuf, defpasscode, 32);
427 CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len);
428 } else {
429 uint8_t test[32], tmpkey[32];
430 FX_DWORD copy_len = sizeof(test);
431 if (copy_len > (FX_DWORD)ukey.GetLength()) {
432 copy_len = ukey.GetLength();
433 }
434 FXSYS_memset(test, 0, sizeof(test));
435 FXSYS_memset(tmpkey, 0, sizeof(tmpkey));
436 FXSYS_memcpy(test, ukey.c_str(), copy_len);
437 for (int i = 19; i >= 0; i--) {
438 for (int j = 0; j < key_len; j++) {
439 tmpkey[j] = key[j] ^ i;
440 }
441 CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len);
442 }
443 uint8_t md5[100];
444 CRYPT_MD5Start(md5);
445 CRYPT_MD5Update(md5, defpasscode, 32);
446 CPDF_Array* pIdArray = m_pParser->GetIDArray();
447 if (pIdArray) {
448 CFX_ByteString id = pIdArray->GetString(0);
449 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
450 }
451 CRYPT_MD5Finish(md5, ukeybuf);
452 return FXSYS_memcmp(test, ukeybuf, 16) == 0;
453 }
454 if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) {
455 return TRUE;
456 }
457 return FALSE;
458 }
GetUserPassword(const uint8_t * owner_pass,FX_DWORD pass_size)459 CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(
460 const uint8_t* owner_pass,
461 FX_DWORD pass_size) {
462 return GetUserPassword(owner_pass, pass_size, m_KeyLen);
463 }
GetUserPassword(const uint8_t * owner_pass,FX_DWORD pass_size,int32_t key_len)464 CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(
465 const uint8_t* owner_pass,
466 FX_DWORD pass_size,
467 int32_t key_len) {
468 CFX_ByteString okey = m_pEncryptDict->GetString("O");
469 uint8_t passcode[32];
470 FX_DWORD i;
471 for (i = 0; i < 32; i++) {
472 passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size];
473 }
474 uint8_t digest[16];
475 CRYPT_MD5Generate(passcode, 32, digest);
476 if (m_Revision >= 3) {
477 for (int i = 0; i < 50; i++) {
478 CRYPT_MD5Generate(digest, 16, digest);
479 }
480 }
481 uint8_t enckey[32];
482 FXSYS_memset(enckey, 0, sizeof(enckey));
483 FX_DWORD copy_len = key_len;
484 if (copy_len > sizeof(digest)) {
485 copy_len = sizeof(digest);
486 }
487 FXSYS_memcpy(enckey, digest, copy_len);
488 int okeylen = okey.GetLength();
489 if (okeylen > 32) {
490 okeylen = 32;
491 }
492 uint8_t okeybuf[64];
493 FXSYS_memset(okeybuf, 0, sizeof(okeybuf));
494 FXSYS_memcpy(okeybuf, okey.c_str(), okeylen);
495 if (m_Revision == 2) {
496 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len);
497 } else {
498 for (int i = 19; i >= 0; i--) {
499 uint8_t tempkey[32];
500 FXSYS_memset(tempkey, 0, sizeof(tempkey));
501 for (int j = 0; j < m_KeyLen; j++) {
502 tempkey[j] = enckey[j] ^ i;
503 }
504 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len);
505 }
506 }
507 int len = 32;
508 while (len && defpasscode[len - 1] == okeybuf[len - 1]) {
509 len--;
510 }
511 return CFX_ByteString(okeybuf, len);
512 }
CheckOwnerPassword(const uint8_t * password,FX_DWORD pass_size,uint8_t * key,int32_t key_len)513 FX_BOOL CPDF_StandardSecurityHandler::CheckOwnerPassword(
514 const uint8_t* password,
515 FX_DWORD pass_size,
516 uint8_t* key,
517 int32_t key_len) {
518 CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len);
519 if (CheckUserPassword(user_pass, user_pass.GetLength(), FALSE, key,
520 key_len)) {
521 return TRUE;
522 }
523 return CheckUserPassword(user_pass, user_pass.GetLength(), TRUE, key,
524 key_len);
525 }
IsMetadataEncrypted()526 FX_BOOL CPDF_StandardSecurityHandler::IsMetadataEncrypted() {
527 return m_pEncryptDict->GetBoolean("EncryptMetadata", TRUE);
528 }
FPDF_CreateStandardSecurityHandler()529 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler() {
530 return new CPDF_StandardSecurityHandler;
531 }
OnCreate(CPDF_Dictionary * pEncryptDict,CPDF_Array * pIdArray,const uint8_t * user_pass,FX_DWORD user_size,const uint8_t * owner_pass,FX_DWORD owner_size,FX_BOOL bDefault,FX_DWORD type)532 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
533 CPDF_Array* pIdArray,
534 const uint8_t* user_pass,
535 FX_DWORD user_size,
536 const uint8_t* owner_pass,
537 FX_DWORD owner_size,
538 FX_BOOL bDefault,
539 FX_DWORD type) {
540 int cipher = 0, key_len = 0;
541 if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
542 return;
543 }
544 if (bDefault && (!owner_pass || owner_size == 0)) {
545 owner_pass = user_pass;
546 owner_size = user_size;
547 }
548 if (m_Revision >= 5) {
549 int t = (int)time(NULL);
550 uint8_t sha[128];
551 CRYPT_SHA256Start(sha);
552 CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t);
553 CRYPT_SHA256Update(sha, m_EncryptKey, 32);
554 CRYPT_SHA256Update(sha, (uint8_t*)"there", 5);
555 CRYPT_SHA256Finish(sha, m_EncryptKey);
556 AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey);
557 if (bDefault) {
558 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE,
559 m_EncryptKey);
560 AES256_SetPerms(pEncryptDict, m_Permissions,
561 pEncryptDict->GetBoolean("EncryptMetadata", TRUE),
562 m_EncryptKey);
563 }
564 return;
565 }
566 if (bDefault) {
567 uint8_t passcode[32];
568 FX_DWORD i;
569 for (i = 0; i < 32; i++) {
570 passcode[i] =
571 i < owner_size ? owner_pass[i] : defpasscode[i - owner_size];
572 }
573 uint8_t digest[16];
574 CRYPT_MD5Generate(passcode, 32, digest);
575 if (m_Revision >= 3) {
576 for (int i = 0; i < 50; i++) {
577 CRYPT_MD5Generate(digest, 16, digest);
578 }
579 }
580 uint8_t enckey[32];
581 FXSYS_memcpy(enckey, digest, key_len);
582 for (i = 0; i < 32; i++) {
583 passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size];
584 }
585 CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len);
586 uint8_t tempkey[32];
587 if (m_Revision >= 3) {
588 for (i = 1; i <= 19; i++) {
589 for (int j = 0; j < key_len; j++) {
590 tempkey[j] = enckey[j] ^ (uint8_t)i;
591 }
592 CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len);
593 }
594 }
595 pEncryptDict->SetAtString("O", CFX_ByteString(passcode, 32));
596 }
597 CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey,
598 key_len, FALSE, pIdArray);
599 if (m_Revision < 3) {
600 uint8_t tempbuf[32];
601 FXSYS_memcpy(tempbuf, defpasscode, 32);
602 CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len);
603 pEncryptDict->SetAtString("U", CFX_ByteString(tempbuf, 32));
604 } else {
605 uint8_t md5[100];
606 CRYPT_MD5Start(md5);
607 CRYPT_MD5Update(md5, defpasscode, 32);
608 if (pIdArray) {
609 CFX_ByteString id = pIdArray->GetString(0);
610 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
611 }
612 uint8_t digest[32];
613 CRYPT_MD5Finish(md5, digest);
614 CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len);
615 uint8_t tempkey[32];
616 for (int i = 1; i <= 19; i++) {
617 for (int j = 0; j < key_len; j++) {
618 tempkey[j] = m_EncryptKey[j] ^ (uint8_t)i;
619 }
620 CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len);
621 }
622 CRYPT_MD5Generate(digest, 16, digest + 16);
623 pEncryptDict->SetAtString("U", CFX_ByteString(digest, 32));
624 }
625 }
OnCreate(CPDF_Dictionary * pEncryptDict,CPDF_Array * pIdArray,const uint8_t * user_pass,FX_DWORD user_size,const uint8_t * owner_pass,FX_DWORD owner_size,FX_DWORD type)626 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
627 CPDF_Array* pIdArray,
628 const uint8_t* user_pass,
629 FX_DWORD user_size,
630 const uint8_t* owner_pass,
631 FX_DWORD owner_size,
632 FX_DWORD type) {
633 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size,
634 TRUE, type);
635 }
OnCreate(CPDF_Dictionary * pEncryptDict,CPDF_Array * pIdArray,const uint8_t * user_pass,FX_DWORD user_size,FX_DWORD type)636 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
637 CPDF_Array* pIdArray,
638 const uint8_t* user_pass,
639 FX_DWORD user_size,
640 FX_DWORD type) {
641 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, NULL, 0, FALSE, type);
642 }
AES256_SetPassword(CPDF_Dictionary * pEncryptDict,const uint8_t * password,FX_DWORD size,FX_BOOL bOwner,const uint8_t * key)643 void CPDF_StandardSecurityHandler::AES256_SetPassword(
644 CPDF_Dictionary* pEncryptDict,
645 const uint8_t* password,
646 FX_DWORD size,
647 FX_BOOL bOwner,
648 const uint8_t* key) {
649 uint8_t sha[128];
650 CRYPT_SHA1Start(sha);
651 CRYPT_SHA1Update(sha, key, 32);
652 CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5);
653 uint8_t digest[20];
654 CRYPT_SHA1Finish(sha, digest);
655 CFX_ByteString ukey = pEncryptDict->GetString("U");
656 uint8_t digest1[48];
657 if (m_Revision >= 6) {
658 Revision6_Hash(password, size, digest,
659 (bOwner ? (const uint8_t*)ukey : NULL), digest1);
660 } else {
661 CRYPT_SHA256Start(sha);
662 CRYPT_SHA256Update(sha, password, size);
663 CRYPT_SHA256Update(sha, digest, 8);
664 if (bOwner) {
665 CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
666 }
667 CRYPT_SHA256Finish(sha, digest1);
668 }
669 FXSYS_memcpy(digest1 + 32, digest, 16);
670 pEncryptDict->SetAtString(bOwner ? "O" : "U", CFX_ByteString(digest1, 48));
671 if (m_Revision >= 6) {
672 Revision6_Hash(password, size, digest + 8,
673 (bOwner ? (const uint8_t*)ukey : NULL), digest1);
674 } else {
675 CRYPT_SHA256Start(sha);
676 CRYPT_SHA256Update(sha, password, size);
677 CRYPT_SHA256Update(sha, digest + 8, 8);
678 if (bOwner) {
679 CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
680 }
681 CRYPT_SHA256Finish(sha, digest1);
682 }
683 uint8_t* aes = FX_Alloc(uint8_t, 2048);
684 CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE);
685 uint8_t iv[16];
686 FXSYS_memset(iv, 0, 16);
687 CRYPT_AESSetIV(aes, iv);
688 CRYPT_AESEncrypt(aes, digest1, key, 32);
689 FX_Free(aes);
690 pEncryptDict->SetAtString(bOwner ? "OE" : "UE", CFX_ByteString(digest1, 32));
691 }
AES256_SetPerms(CPDF_Dictionary * pEncryptDict,FX_DWORD permissions,FX_BOOL bEncryptMetadata,const uint8_t * key)692 void CPDF_StandardSecurityHandler::AES256_SetPerms(
693 CPDF_Dictionary* pEncryptDict,
694 FX_DWORD permissions,
695 FX_BOOL bEncryptMetadata,
696 const uint8_t* key) {
697 uint8_t buf[16];
698 buf[0] = (uint8_t)permissions;
699 buf[1] = (uint8_t)(permissions >> 8);
700 buf[2] = (uint8_t)(permissions >> 16);
701 buf[3] = (uint8_t)(permissions >> 24);
702 buf[4] = 0xff;
703 buf[5] = 0xff;
704 buf[6] = 0xff;
705 buf[7] = 0xff;
706 buf[8] = bEncryptMetadata ? 'T' : 'F';
707 buf[9] = 'a';
708 buf[10] = 'd';
709 buf[11] = 'b';
710 uint8_t* aes = FX_Alloc(uint8_t, 2048);
711 CRYPT_AESSetKey(aes, 16, key, 32, TRUE);
712 uint8_t iv[16], buf1[16];
713 FXSYS_memset(iv, 0, 16);
714 CRYPT_AESSetIV(aes, iv);
715 CRYPT_AESEncrypt(aes, buf1, buf, 16);
716 FX_Free(aes);
717 pEncryptDict->SetAtString("Perms", CFX_ByteString(buf1, 16));
718 }
CryptBlock(FX_BOOL bEncrypt,FX_DWORD objnum,FX_DWORD gennum,const uint8_t * src_buf,FX_DWORD src_size,uint8_t * dest_buf,FX_DWORD & dest_size)719 void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt,
720 FX_DWORD objnum,
721 FX_DWORD gennum,
722 const uint8_t* src_buf,
723 FX_DWORD src_size,
724 uint8_t* dest_buf,
725 FX_DWORD& dest_size) {
726 if (m_Cipher == FXCIPHER_NONE) {
727 FXSYS_memcpy(dest_buf, src_buf, src_size);
728 return;
729 }
730 uint8_t realkey[16];
731 int realkeylen = 16;
732 if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) {
733 uint8_t key1[32];
734 FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen);
735 key1[m_KeyLen + 0] = (uint8_t)objnum;
736 key1[m_KeyLen + 1] = (uint8_t)(objnum >> 8);
737 key1[m_KeyLen + 2] = (uint8_t)(objnum >> 16);
738 key1[m_KeyLen + 3] = (uint8_t)gennum;
739 key1[m_KeyLen + 4] = (uint8_t)(gennum >> 8);
740 FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3);
741 FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2);
742 if (m_Cipher == FXCIPHER_AES) {
743 FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
744 }
745 CRYPT_MD5Generate(
746 key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
747 realkeylen = m_KeyLen + 5;
748 if (realkeylen > 16) {
749 realkeylen = 16;
750 }
751 }
752 if (m_Cipher == FXCIPHER_AES) {
753 CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey,
754 m_KeyLen, bEncrypt);
755 if (bEncrypt) {
756 uint8_t iv[16];
757 for (int i = 0; i < 16; i++) {
758 iv[i] = (uint8_t)rand();
759 }
760 CRYPT_AESSetIV(m_pAESContext, iv);
761 FXSYS_memcpy(dest_buf, iv, 16);
762 int nblocks = src_size / 16;
763 CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16);
764 uint8_t padding[16];
765 FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16);
766 FXSYS_memset(padding + src_size % 16, 16 - src_size % 16,
767 16 - src_size % 16);
768 CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding,
769 16);
770 dest_size = 32 + nblocks * 16;
771 } else {
772 CRYPT_AESSetIV(m_pAESContext, src_buf);
773 CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16);
774 dest_size = src_size - 16;
775 dest_size -= dest_buf[dest_size - 1];
776 }
777 } else {
778 ASSERT(dest_size == src_size);
779 if (dest_buf != src_buf) {
780 FXSYS_memcpy(dest_buf, src_buf, src_size);
781 }
782 CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen);
783 }
784 }
785 typedef struct _AESCryptContext {
786 uint8_t m_Context[2048];
787 FX_BOOL m_bIV;
788 uint8_t m_Block[16];
789 FX_DWORD m_BlockOffset;
790 } AESCryptContext;
CryptStart(FX_DWORD objnum,FX_DWORD gennum,FX_BOOL bEncrypt)791 void* CPDF_StandardCryptoHandler::CryptStart(FX_DWORD objnum,
792 FX_DWORD gennum,
793 FX_BOOL bEncrypt) {
794 if (m_Cipher == FXCIPHER_NONE) {
795 return this;
796 }
797 if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) {
798 AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
799 pContext->m_bIV = TRUE;
800 pContext->m_BlockOffset = 0;
801 CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt);
802 if (bEncrypt) {
803 for (int i = 0; i < 16; i++) {
804 pContext->m_Block[i] = (uint8_t)rand();
805 }
806 CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
807 }
808 return pContext;
809 }
810 uint8_t key1[48];
811 FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen);
812 FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3);
813 FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2);
814 if (m_Cipher == FXCIPHER_AES) {
815 FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
816 }
817 uint8_t realkey[16];
818 CRYPT_MD5Generate(
819 key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
820 int realkeylen = m_KeyLen + 5;
821 if (realkeylen > 16) {
822 realkeylen = 16;
823 }
824 if (m_Cipher == FXCIPHER_AES) {
825 AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
826 pContext->m_bIV = TRUE;
827 pContext->m_BlockOffset = 0;
828 CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt);
829 if (bEncrypt) {
830 for (int i = 0; i < 16; i++) {
831 pContext->m_Block[i] = (uint8_t)rand();
832 }
833 CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
834 }
835 return pContext;
836 }
837 void* pContext = FX_Alloc(uint8_t, 1040);
838 CRYPT_ArcFourSetup(pContext, realkey, realkeylen);
839 return pContext;
840 }
CryptStream(void * context,const uint8_t * src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf,FX_BOOL bEncrypt)841 FX_BOOL CPDF_StandardCryptoHandler::CryptStream(void* context,
842 const uint8_t* src_buf,
843 FX_DWORD src_size,
844 CFX_BinaryBuf& dest_buf,
845 FX_BOOL bEncrypt) {
846 if (!context) {
847 return FALSE;
848 }
849 if (m_Cipher == FXCIPHER_NONE) {
850 dest_buf.AppendBlock(src_buf, src_size);
851 return TRUE;
852 }
853 if (m_Cipher == FXCIPHER_RC4) {
854 int old_size = dest_buf.GetSize();
855 dest_buf.AppendBlock(src_buf, src_size);
856 CRYPT_ArcFourCrypt(context, dest_buf.GetBuffer() + old_size, src_size);
857 return TRUE;
858 }
859 AESCryptContext* pContext = (AESCryptContext*)context;
860 if (pContext->m_bIV && bEncrypt) {
861 dest_buf.AppendBlock(pContext->m_Block, 16);
862 pContext->m_bIV = FALSE;
863 }
864 FX_DWORD src_off = 0;
865 FX_DWORD src_left = src_size;
866 while (1) {
867 FX_DWORD copy_size = 16 - pContext->m_BlockOffset;
868 if (copy_size > src_left) {
869 copy_size = src_left;
870 }
871 FXSYS_memcpy(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off,
872 copy_size);
873 src_off += copy_size;
874 src_left -= copy_size;
875 pContext->m_BlockOffset += copy_size;
876 if (pContext->m_BlockOffset == 16) {
877 if (!bEncrypt && pContext->m_bIV) {
878 CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
879 pContext->m_bIV = FALSE;
880 pContext->m_BlockOffset = 0;
881 } else if (src_off < src_size) {
882 uint8_t block_buf[16];
883 if (bEncrypt) {
884 CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block,
885 16);
886 } else {
887 CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block,
888 16);
889 }
890 dest_buf.AppendBlock(block_buf, 16);
891 pContext->m_BlockOffset = 0;
892 }
893 }
894 if (!src_left) {
895 break;
896 }
897 }
898 return TRUE;
899 }
CryptFinish(void * context,CFX_BinaryBuf & dest_buf,FX_BOOL bEncrypt)900 FX_BOOL CPDF_StandardCryptoHandler::CryptFinish(void* context,
901 CFX_BinaryBuf& dest_buf,
902 FX_BOOL bEncrypt) {
903 if (!context) {
904 return FALSE;
905 }
906 if (m_Cipher == FXCIPHER_NONE) {
907 return TRUE;
908 }
909 if (m_Cipher == FXCIPHER_RC4) {
910 FX_Free(context);
911 return TRUE;
912 }
913 AESCryptContext* pContext = (AESCryptContext*)context;
914 if (bEncrypt) {
915 uint8_t block_buf[16];
916 if (pContext->m_BlockOffset == 16) {
917 CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
918 dest_buf.AppendBlock(block_buf, 16);
919 pContext->m_BlockOffset = 0;
920 }
921 FXSYS_memset(pContext->m_Block + pContext->m_BlockOffset,
922 (uint8_t)(16 - pContext->m_BlockOffset),
923 16 - pContext->m_BlockOffset);
924 CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
925 dest_buf.AppendBlock(block_buf, 16);
926 } else if (pContext->m_BlockOffset == 16) {
927 uint8_t block_buf[16];
928 CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
929 if (block_buf[15] <= 16) {
930 dest_buf.AppendBlock(block_buf, 16 - block_buf[15]);
931 }
932 }
933 FX_Free(pContext);
934 return TRUE;
935 }
DecryptStart(FX_DWORD objnum,FX_DWORD gennum)936 void* CPDF_StandardCryptoHandler::DecryptStart(FX_DWORD objnum,
937 FX_DWORD gennum) {
938 return CryptStart(objnum, gennum, FALSE);
939 }
DecryptGetSize(FX_DWORD src_size)940 FX_DWORD CPDF_StandardCryptoHandler::DecryptGetSize(FX_DWORD src_size) {
941 return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size;
942 }
Init(CPDF_Dictionary * pEncryptDict,CPDF_SecurityHandler * pSecurityHandler)943 FX_BOOL CPDF_StandardCryptoHandler::Init(
944 CPDF_Dictionary* pEncryptDict,
945 CPDF_SecurityHandler* pSecurityHandler) {
946 const uint8_t* key;
947 if (!pSecurityHandler->GetCryptInfo(m_Cipher, key, m_KeyLen)) {
948 return FALSE;
949 }
950 if (m_KeyLen > 32 || m_KeyLen < 0) {
951 return FALSE;
952 }
953 if (m_Cipher != FXCIPHER_NONE) {
954 FXSYS_memcpy(m_EncryptKey, key, m_KeyLen);
955 }
956 if (m_Cipher == FXCIPHER_AES) {
957 m_pAESContext = FX_Alloc(uint8_t, 2048);
958 }
959 return TRUE;
960 }
Init(int cipher,const uint8_t * key,int keylen)961 FX_BOOL CPDF_StandardCryptoHandler::Init(int cipher,
962 const uint8_t* key,
963 int keylen) {
964 if (cipher == FXCIPHER_AES) {
965 switch (keylen) {
966 case 16:
967 case 24:
968 case 32:
969 break;
970 default:
971 return FALSE;
972 }
973 } else if (cipher == FXCIPHER_AES2) {
974 if (keylen != 32) {
975 return FALSE;
976 }
977 } else if (cipher == FXCIPHER_RC4) {
978 if (keylen < 5 || keylen > 16) {
979 return FALSE;
980 }
981 } else {
982 if (keylen > 32) {
983 keylen = 32;
984 }
985 }
986 m_Cipher = cipher;
987 m_KeyLen = keylen;
988 FXSYS_memcpy(m_EncryptKey, key, keylen);
989 if (m_Cipher == FXCIPHER_AES) {
990 m_pAESContext = FX_Alloc(uint8_t, 2048);
991 }
992 return TRUE;
993 }
DecryptStream(void * context,const uint8_t * src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)994 FX_BOOL CPDF_StandardCryptoHandler::DecryptStream(void* context,
995 const uint8_t* src_buf,
996 FX_DWORD src_size,
997 CFX_BinaryBuf& dest_buf) {
998 return CryptStream(context, src_buf, src_size, dest_buf, FALSE);
999 }
DecryptFinish(void * context,CFX_BinaryBuf & dest_buf)1000 FX_BOOL CPDF_StandardCryptoHandler::DecryptFinish(void* context,
1001 CFX_BinaryBuf& dest_buf) {
1002 return CryptFinish(context, dest_buf, FALSE);
1003 }
EncryptGetSize(FX_DWORD objnum,FX_DWORD version,const uint8_t * src_buf,FX_DWORD src_size)1004 FX_DWORD CPDF_StandardCryptoHandler::EncryptGetSize(FX_DWORD objnum,
1005 FX_DWORD version,
1006 const uint8_t* src_buf,
1007 FX_DWORD src_size) {
1008 if (m_Cipher == FXCIPHER_AES) {
1009 return src_size + 32;
1010 }
1011 return src_size;
1012 }
EncryptContent(FX_DWORD objnum,FX_DWORD gennum,const uint8_t * src_buf,FX_DWORD src_size,uint8_t * dest_buf,FX_DWORD & dest_size)1013 FX_BOOL CPDF_StandardCryptoHandler::EncryptContent(FX_DWORD objnum,
1014 FX_DWORD gennum,
1015 const uint8_t* src_buf,
1016 FX_DWORD src_size,
1017 uint8_t* dest_buf,
1018 FX_DWORD& dest_size) {
1019 CryptBlock(TRUE, objnum, gennum, src_buf, src_size, dest_buf, dest_size);
1020 return TRUE;
1021 }
Decrypt(FX_DWORD objnum,FX_DWORD gennum,CFX_ByteString & str)1022 void CPDF_CryptoHandler::Decrypt(FX_DWORD objnum,
1023 FX_DWORD gennum,
1024 CFX_ByteString& str) {
1025 CFX_BinaryBuf dest_buf;
1026 void* context = DecryptStart(objnum, gennum);
1027 DecryptStream(context, (const uint8_t*)str, str.GetLength(), dest_buf);
1028 DecryptFinish(context, dest_buf);
1029 str = dest_buf;
1030 }
CPDF_StandardCryptoHandler()1031 CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler() {
1032 m_pAESContext = NULL;
1033 m_Cipher = FXCIPHER_NONE;
1034 m_KeyLen = 0;
1035 }
~CPDF_StandardCryptoHandler()1036 CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler() {
1037 FX_Free(m_pAESContext);
1038 }
1039