Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp

Issue 1898173002: Remove IPDF_CryptoHandler and IPDF_SecurityHandler. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/fpdfapi/fpdf_parser/cpdf_standard_security_handler.h"
8
9 #include <time.h>
10
11 #include "core/fdrm/crypto/include/fx_crypt.h"
12 #include "core/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
14 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
15 #include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
16 #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h"
17
18 namespace {
19
20 const uint8_t defpasscode[32] = {
21 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e,
22 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68,
23 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a};
24
25 void CalcEncryptKey(CPDF_Dictionary* pEncrypt,
26 const uint8_t* password,
27 uint32_t pass_size,
28 uint8_t* key,
29 int keylen,
30 FX_BOOL bIgnoreMeta,
31 CPDF_Array* pIdArray) {
32 int revision = pEncrypt->GetIntegerBy("R");
33 uint8_t passcode[32];
34 for (uint32_t i = 0; i < 32; i++) {
35 passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size];
36 }
37 uint8_t md5[100];
38 CRYPT_MD5Start(md5);
39 CRYPT_MD5Update(md5, passcode, 32);
40 CFX_ByteString okey = pEncrypt->GetStringBy("O");
41 CRYPT_MD5Update(md5, (uint8_t*)okey.c_str(), okey.GetLength());
42 uint32_t perm = pEncrypt->GetIntegerBy("P");
43 CRYPT_MD5Update(md5, (uint8_t*)&perm, 4);
44 if (pIdArray) {
45 CFX_ByteString id = pIdArray->GetStringAt(0);
46 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
47 }
48 if (!bIgnoreMeta && revision >= 3 &&
49 !pEncrypt->GetIntegerBy("EncryptMetadata", 1)) {
50 uint32_t tag = (uint32_t)-1;
51 CRYPT_MD5Update(md5, (uint8_t*)&tag, 4);
52 }
53 uint8_t digest[16];
54 CRYPT_MD5Finish(md5, digest);
55 uint32_t copy_len = keylen;
56 if (copy_len > sizeof(digest)) {
57 copy_len = sizeof(digest);
58 }
59 if (revision >= 3) {
60 for (int i = 0; i < 50; i++) {
61 CRYPT_MD5Generate(digest, copy_len, digest);
62 }
63 }
64 FXSYS_memset(key, 0, keylen);
65 FXSYS_memcpy(key, digest, copy_len);
66 }
67
68 } // namespace
69
70 IPDF_SecurityHandler::~IPDF_SecurityHandler() {}
71
72 CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler() {
73 m_Version = 0;
74 m_Revision = 0;
75 m_pParser = NULL;
76 m_pEncryptDict = NULL;
77 m_Permissions = 0;
78 m_Cipher = FXCIPHER_NONE;
79 m_KeyLen = 0;
80 }
81
82 CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler() {}
83
84 IPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler() {
85 return new CPDF_StandardCryptoHandler;
86 }
87
88 FX_BOOL CPDF_StandardSecurityHandler::OnInit(CPDF_Parser* pParser,
89 CPDF_Dictionary* pEncryptDict) {
90 m_pParser = pParser;
91 if (!LoadDict(pEncryptDict)) {
92 return FALSE;
93 }
94 if (m_Cipher == FXCIPHER_NONE) {
95 return TRUE;
96 }
97 return CheckSecurity(m_KeyLen);
98 }
99 FX_BOOL CPDF_StandardSecurityHandler::CheckSecurity(int32_t key_len) {
100 CFX_ByteString password = m_pParser->GetPassword();
101 if (CheckPassword(password.raw_str(), password.GetLength(), TRUE,
102 m_EncryptKey, key_len)) {
103 if (password.IsEmpty()) {
104 if (!CheckPassword(password.raw_str(), password.GetLength(), FALSE,
105 m_EncryptKey, key_len)) {
106 return FALSE;
107 }
108 }
109 return TRUE;
110 }
111 return CheckPassword(password.raw_str(), password.GetLength(), FALSE,
112 m_EncryptKey, key_len);
113 }
114 uint32_t CPDF_StandardSecurityHandler::GetPermissions() {
115 return m_Permissions;
116 }
117 static FX_BOOL _LoadCryptInfo(CPDF_Dictionary* pEncryptDict,
118 const CFX_ByteStringC& name,
119 int& cipher,
120 int& keylen) {
121 int Version = pEncryptDict->GetIntegerBy("V");
122 cipher = FXCIPHER_RC4;
123 keylen = 0;
124 if (Version >= 4) {
125 CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDictBy("CF");
126 if (!pCryptFilters) {
127 return FALSE;
128 }
129 if (name == "Identity") {
130 cipher = FXCIPHER_NONE;
131 } else {
132 CPDF_Dictionary* pDefFilter = pCryptFilters->GetDictBy(name);
133 if (!pDefFilter) {
134 return FALSE;
135 }
136 int nKeyBits = 0;
137 if (Version == 4) {
138 nKeyBits = pDefFilter->GetIntegerBy("Length", 0);
139 if (nKeyBits == 0) {
140 nKeyBits = pEncryptDict->GetIntegerBy("Length", 128);
141 }
142 } else {
143 nKeyBits = pEncryptDict->GetIntegerBy("Length", 256);
144 }
145 if (nKeyBits < 40) {
146 nKeyBits *= 8;
147 }
148 keylen = nKeyBits / 8;
149 CFX_ByteString cipher_name = pDefFilter->GetStringBy("CFM");
150 if (cipher_name == "AESV2" || cipher_name == "AESV3") {
151 cipher = FXCIPHER_AES;
152 }
153 }
154 } else {
155 keylen = Version > 1 ? pEncryptDict->GetIntegerBy("Length", 40) / 8 : 5;
156 }
157 if (keylen > 32 || keylen < 0) {
158 return FALSE;
159 }
160 return TRUE;
161 }
162
163 FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) {
164 m_pEncryptDict = pEncryptDict;
165 m_Version = pEncryptDict->GetIntegerBy("V");
166 m_Revision = pEncryptDict->GetIntegerBy("R");
167 m_Permissions = pEncryptDict->GetIntegerBy("P", -1);
168 if (m_Version < 4) {
169 return _LoadCryptInfo(pEncryptDict, CFX_ByteStringC(), m_Cipher, m_KeyLen);
170 }
171 CFX_ByteString stmf_name = pEncryptDict->GetStringBy("StmF");
172 CFX_ByteString strf_name = pEncryptDict->GetStringBy("StrF");
173 if (stmf_name != strf_name) {
174 return FALSE;
175 }
176 if (!_LoadCryptInfo(pEncryptDict, strf_name.AsStringC(), m_Cipher,
177 m_KeyLen)) {
178 return FALSE;
179 }
180 return TRUE;
181 }
182
183 FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict,
184 uint32_t type,
185 int& cipher,
186 int& key_len) {
187 m_pEncryptDict = pEncryptDict;
188 m_Version = pEncryptDict->GetIntegerBy("V");
189 m_Revision = pEncryptDict->GetIntegerBy("R");
190 m_Permissions = pEncryptDict->GetIntegerBy("P", -1);
191 CFX_ByteString strf_name, stmf_name;
192 if (m_Version >= 4) {
193 stmf_name = pEncryptDict->GetStringBy("StmF");
194 strf_name = pEncryptDict->GetStringBy("StrF");
195 if (stmf_name != strf_name) {
196 return FALSE;
197 }
198 }
199 if (!_LoadCryptInfo(pEncryptDict, strf_name.AsStringC(), cipher, key_len)) {
200 return FALSE;
201 }
202 m_Cipher = cipher;
203 m_KeyLen = key_len;
204 return TRUE;
205 }
206
207 FX_BOOL CPDF_StandardSecurityHandler::GetCryptInfo(int& cipher,
208 const uint8_t*& buffer,
209 int& keylen) {
210 cipher = m_Cipher;
211 buffer = m_EncryptKey;
212 keylen = m_KeyLen;
213 return TRUE;
214 }
215 #define FX_GET_32WORD(n, b, i) \
216 { \
217 (n) = (uint32_t)( \
218 ((uint64_t)(b)[(i)] << 24) | ((uint64_t)(b)[(i) + 1] << 16) | \
219 ((uint64_t)(b)[(i) + 2] << 8) | ((uint64_t)(b)[(i) + 3])); \
220 }
221 int BigOrder64BitsMod3(uint8_t* data) {
222 uint64_t ret = 0;
223 for (int i = 0; i < 4; ++i) {
224 uint32_t value;
225 FX_GET_32WORD(value, data, 4 * i);
226 ret <<= 32;
227 ret |= value;
228 ret %= 3;
229 }
230 return (int)ret;
231 }
232 void Revision6_Hash(const uint8_t* password,
233 uint32_t size,
234 const uint8_t* salt,
235 const uint8_t* vector,
236 uint8_t* hash) {
237 int iBlockSize = 32;
238 uint8_t sha[128];
239 CRYPT_SHA256Start(sha);
240 CRYPT_SHA256Update(sha, password, size);
241 CRYPT_SHA256Update(sha, salt, 8);
242 if (vector) {
243 CRYPT_SHA256Update(sha, vector, 48);
244 }
245 uint8_t digest[32];
246 CRYPT_SHA256Finish(sha, digest);
247 CFX_ByteTextBuf buf;
248 uint8_t* input = digest;
249 uint8_t* key = input;
250 uint8_t* iv = input + 16;
251 uint8_t* E = buf.GetBuffer();
252 int iBufLen = buf.GetLength();
253 CFX_ByteTextBuf interDigest;
254 int i = 0;
255 uint8_t* aes = FX_Alloc(uint8_t, 2048);
256 while (i < 64 || i < E[iBufLen - 1] + 32) {
257 int iRoundSize = size + iBlockSize;
258 if (vector) {
259 iRoundSize += 48;
260 }
261 iBufLen = iRoundSize * 64;
262 buf.EstimateSize(iBufLen);
263 E = buf.GetBuffer();
264 CFX_ByteTextBuf content;
265 for (int j = 0; j < 64; ++j) {
266 content.AppendBlock(password, size);
267 content.AppendBlock(input, iBlockSize);
268 if (vector) {
269 content.AppendBlock(vector, 48);
270 }
271 }
272 CRYPT_AESSetKey(aes, 16, key, 16, TRUE);
273 CRYPT_AESSetIV(aes, iv);
274 CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen);
275 int iHash = 0;
276 switch (BigOrder64BitsMod3(E)) {
277 case 0:
278 iHash = 0;
279 iBlockSize = 32;
280 break;
281 case 1:
282 iHash = 1;
283 iBlockSize = 48;
284 break;
285 default:
286 iHash = 2;
287 iBlockSize = 64;
288 break;
289 }
290 interDigest.EstimateSize(iBlockSize);
291 input = interDigest.GetBuffer();
292 if (iHash == 0) {
293 CRYPT_SHA256Generate(E, iBufLen, input);
294 } else if (iHash == 1) {
295 CRYPT_SHA384Generate(E, iBufLen, input);
296 } else if (iHash == 2) {
297 CRYPT_SHA512Generate(E, iBufLen, input);
298 }
299 key = input;
300 iv = input + 16;
301 ++i;
302 }
303 FX_Free(aes);
304 if (hash) {
305 FXSYS_memcpy(hash, input, 32);
306 }
307 }
308 FX_BOOL CPDF_StandardSecurityHandler::AES256_CheckPassword(
309 const uint8_t* password,
310 uint32_t size,
311 FX_BOOL bOwner,
312 uint8_t* key) {
313 CFX_ByteString okey =
314 m_pEncryptDict ? m_pEncryptDict->GetStringBy("O") : CFX_ByteString();
315 if (okey.GetLength() < 48) {
316 return FALSE;
317 }
318 CFX_ByteString ukey =
319 m_pEncryptDict ? m_pEncryptDict->GetStringBy("U") : CFX_ByteString();
320 if (ukey.GetLength() < 48) {
321 return FALSE;
322 }
323 const uint8_t* pkey = (bOwner ? okey : ukey).raw_str();
324 uint8_t sha[128];
325 uint8_t digest[32];
326 if (m_Revision >= 6) {
327 Revision6_Hash(password, size, (const uint8_t*)pkey + 32,
328 bOwner ? ukey.raw_str() : nullptr, digest);
329 } else {
330 CRYPT_SHA256Start(sha);
331 CRYPT_SHA256Update(sha, password, size);
332 CRYPT_SHA256Update(sha, pkey + 32, 8);
333 if (bOwner) {
334 CRYPT_SHA256Update(sha, ukey.raw_str(), 48);
335 }
336 CRYPT_SHA256Finish(sha, digest);
337 }
338 if (FXSYS_memcmp(digest, pkey, 32) != 0) {
339 return FALSE;
340 }
341 if (!key) {
342 return TRUE;
343 }
344 if (m_Revision >= 6) {
345 Revision6_Hash(password, size, (const uint8_t*)pkey + 40,
346 bOwner ? ukey.raw_str() : nullptr, digest);
347 } else {
348 CRYPT_SHA256Start(sha);
349 CRYPT_SHA256Update(sha, password, size);
350 CRYPT_SHA256Update(sha, pkey + 40, 8);
351 if (bOwner) {
352 CRYPT_SHA256Update(sha, ukey.raw_str(), 48);
353 }
354 CRYPT_SHA256Finish(sha, digest);
355 }
356 CFX_ByteString ekey = m_pEncryptDict
357 ? m_pEncryptDict->GetStringBy(bOwner ? "OE" : "UE")
358 : CFX_ByteString();
359 if (ekey.GetLength() < 32) {
360 return FALSE;
361 }
362 uint8_t* aes = FX_Alloc(uint8_t, 2048);
363 CRYPT_AESSetKey(aes, 16, digest, 32, FALSE);
364 uint8_t iv[16];
365 FXSYS_memset(iv, 0, 16);
366 CRYPT_AESSetIV(aes, iv);
367 CRYPT_AESDecrypt(aes, key, ekey.raw_str(), 32);
368 CRYPT_AESSetKey(aes, 16, key, 32, FALSE);
369 CRYPT_AESSetIV(aes, iv);
370 CFX_ByteString perms = m_pEncryptDict->GetStringBy("Perms");
371 if (perms.IsEmpty()) {
372 return FALSE;
373 }
374 uint8_t perms_buf[16];
375 FXSYS_memset(perms_buf, 0, sizeof(perms_buf));
376 uint32_t copy_len = sizeof(perms_buf);
377 if (copy_len > (uint32_t)perms.GetLength()) {
378 copy_len = perms.GetLength();
379 }
380 FXSYS_memcpy(perms_buf, perms.raw_str(), copy_len);
381 uint8_t buf[16];
382 CRYPT_AESDecrypt(aes, buf, perms_buf, 16);
383 FX_Free(aes);
384 if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') {
385 return FALSE;
386 }
387 if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) {
388 return FALSE;
389 }
390 if ((buf[8] == 'T' && !IsMetadataEncrypted()) ||
391 (buf[8] == 'F' && IsMetadataEncrypted())) {
392 return FALSE;
393 }
394 return TRUE;
395 }
396
397 int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password,
398 uint32_t size,
399 FX_BOOL bOwner,
400 uint8_t* key,
401 int32_t key_len) {
402 if (m_Revision >= 5) {
403 return AES256_CheckPassword(password, size, bOwner, key);
404 }
405 uint8_t keybuf[32];
406 if (!key) {
407 key = keybuf;
408 }
409 if (bOwner) {
410 return CheckOwnerPassword(password, size, key, key_len);
411 }
412 return CheckUserPassword(password, size, FALSE, key, key_len) ||
413 CheckUserPassword(password, size, TRUE, key, key_len);
414 }
415 FX_BOOL CPDF_StandardSecurityHandler::CheckUserPassword(
416 const uint8_t* password,
417 uint32_t pass_size,
418 FX_BOOL bIgnoreEncryptMeta,
419 uint8_t* key,
420 int32_t key_len) {
421 CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len,
422 bIgnoreEncryptMeta, m_pParser->GetIDArray());
423 CFX_ByteString ukey =
424 m_pEncryptDict ? m_pEncryptDict->GetStringBy("U") : CFX_ByteString();
425 if (ukey.GetLength() < 16) {
426 return FALSE;
427 }
428 uint8_t ukeybuf[32];
429 if (m_Revision == 2) {
430 FXSYS_memcpy(ukeybuf, defpasscode, 32);
431 CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len);
432 } else {
433 uint8_t test[32], tmpkey[32];
434 uint32_t copy_len = sizeof(test);
435 if (copy_len > (uint32_t)ukey.GetLength()) {
436 copy_len = ukey.GetLength();
437 }
438 FXSYS_memset(test, 0, sizeof(test));
439 FXSYS_memset(tmpkey, 0, sizeof(tmpkey));
440 FXSYS_memcpy(test, ukey.c_str(), copy_len);
441 for (int i = 19; i >= 0; i--) {
442 for (int j = 0; j < key_len; j++) {
443 tmpkey[j] = key[j] ^ i;
444 }
445 CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len);
446 }
447 uint8_t md5[100];
448 CRYPT_MD5Start(md5);
449 CRYPT_MD5Update(md5, defpasscode, 32);
450 CPDF_Array* pIdArray = m_pParser->GetIDArray();
451 if (pIdArray) {
452 CFX_ByteString id = pIdArray->GetStringAt(0);
453 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
454 }
455 CRYPT_MD5Finish(md5, ukeybuf);
456 return FXSYS_memcmp(test, ukeybuf, 16) == 0;
457 }
458 if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) {
459 return TRUE;
460 }
461 return FALSE;
462 }
463 CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(
464 const uint8_t* owner_pass,
465 uint32_t pass_size,
466 int32_t key_len) {
467 CFX_ByteString okey = m_pEncryptDict->GetStringBy("O");
468 uint8_t passcode[32];
469 uint32_t i;
470 for (i = 0; i < 32; i++) {
471 passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size];
472 }
473 uint8_t digest[16];
474 CRYPT_MD5Generate(passcode, 32, digest);
475 if (m_Revision >= 3) {
476 for (int i = 0; i < 50; i++) {
477 CRYPT_MD5Generate(digest, 16, digest);
478 }
479 }
480 uint8_t enckey[32];
481 FXSYS_memset(enckey, 0, sizeof(enckey));
482 uint32_t copy_len = key_len;
483 if (copy_len > sizeof(digest)) {
484 copy_len = sizeof(digest);
485 }
486 FXSYS_memcpy(enckey, digest, copy_len);
487 int okeylen = okey.GetLength();
488 if (okeylen > 32) {
489 okeylen = 32;
490 }
491 uint8_t okeybuf[64];
492 FXSYS_memset(okeybuf, 0, sizeof(okeybuf));
493 FXSYS_memcpy(okeybuf, okey.c_str(), okeylen);
494 if (m_Revision == 2) {
495 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len);
496 } else {
497 for (int i = 19; i >= 0; i--) {
498 uint8_t tempkey[32];
499 FXSYS_memset(tempkey, 0, sizeof(tempkey));
500 for (int j = 0; j < m_KeyLen; j++) {
501 tempkey[j] = enckey[j] ^ i;
502 }
503 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len);
504 }
505 }
506 int len = 32;
507 while (len && defpasscode[len - 1] == okeybuf[len - 1]) {
508 len--;
509 }
510 return CFX_ByteString(okeybuf, len);
511 }
512 FX_BOOL CPDF_StandardSecurityHandler::CheckOwnerPassword(
513 const uint8_t* password,
514 uint32_t pass_size,
515 uint8_t* key,
516 int32_t key_len) {
517 CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len);
518 if (CheckUserPassword(user_pass.raw_str(), user_pass.GetLength(), FALSE, key,
519 key_len)) {
520 return TRUE;
521 }
522 return CheckUserPassword(user_pass.raw_str(), user_pass.GetLength(), TRUE,
523 key, key_len);
524 }
525 FX_BOOL CPDF_StandardSecurityHandler::IsMetadataEncrypted() {
526 return m_pEncryptDict->GetBooleanBy("EncryptMetadata", TRUE);
527 }
528
529 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
530 CPDF_Array* pIdArray,
531 const uint8_t* user_pass,
532 uint32_t user_size,
533 const uint8_t* owner_pass,
534 uint32_t owner_size,
535 FX_BOOL bDefault,
536 uint32_t type) {
537 int cipher = 0, key_len = 0;
538 if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
539 return;
540 }
541 if (bDefault && (!owner_pass || owner_size == 0)) {
542 owner_pass = user_pass;
543 owner_size = user_size;
544 }
545 if (m_Revision >= 5) {
546 int t = (int)time(NULL);
547 uint8_t sha[128];
548 CRYPT_SHA256Start(sha);
549 CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t);
550 CRYPT_SHA256Update(sha, m_EncryptKey, 32);
551 CRYPT_SHA256Update(sha, (uint8_t*)"there", 5);
552 CRYPT_SHA256Finish(sha, m_EncryptKey);
553 AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey);
554 if (bDefault) {
555 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE,
556 m_EncryptKey);
557 AES256_SetPerms(pEncryptDict, m_Permissions,
558 pEncryptDict->GetBooleanBy("EncryptMetadata", TRUE),
559 m_EncryptKey);
560 }
561 return;
562 }
563 if (bDefault) {
564 uint8_t passcode[32];
565 uint32_t i;
566 for (i = 0; i < 32; i++) {
567 passcode[i] =
568 i < owner_size ? owner_pass[i] : defpasscode[i - owner_size];
569 }
570 uint8_t digest[16];
571 CRYPT_MD5Generate(passcode, 32, digest);
572 if (m_Revision >= 3) {
573 for (int i = 0; i < 50; i++) {
574 CRYPT_MD5Generate(digest, 16, digest);
575 }
576 }
577 uint8_t enckey[32];
578 FXSYS_memcpy(enckey, digest, key_len);
579 for (i = 0; i < 32; i++) {
580 passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size];
581 }
582 CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len);
583 uint8_t tempkey[32];
584 if (m_Revision >= 3) {
585 for (i = 1; i <= 19; i++) {
586 for (int j = 0; j < key_len; j++) {
587 tempkey[j] = enckey[j] ^ (uint8_t)i;
588 }
589 CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len);
590 }
591 }
592 pEncryptDict->SetAtString("O", CFX_ByteString(passcode, 32));
593 }
594 CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey,
595 key_len, FALSE, pIdArray);
596 if (m_Revision < 3) {
597 uint8_t tempbuf[32];
598 FXSYS_memcpy(tempbuf, defpasscode, 32);
599 CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len);
600 pEncryptDict->SetAtString("U", CFX_ByteString(tempbuf, 32));
601 } else {
602 uint8_t md5[100];
603 CRYPT_MD5Start(md5);
604 CRYPT_MD5Update(md5, defpasscode, 32);
605 if (pIdArray) {
606 CFX_ByteString id = pIdArray->GetStringAt(0);
607 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
608 }
609 uint8_t digest[32];
610 CRYPT_MD5Finish(md5, digest);
611 CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len);
612 uint8_t tempkey[32];
613 for (int i = 1; i <= 19; i++) {
614 for (int j = 0; j < key_len; j++) {
615 tempkey[j] = m_EncryptKey[j] ^ (uint8_t)i;
616 }
617 CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len);
618 }
619 CRYPT_MD5Generate(digest, 16, digest + 16);
620 pEncryptDict->SetAtString("U", CFX_ByteString(digest, 32));
621 }
622 }
623 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
624 CPDF_Array* pIdArray,
625 const uint8_t* user_pass,
626 uint32_t user_size,
627 const uint8_t* owner_pass,
628 uint32_t owner_size,
629 uint32_t type) {
630 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size,
631 TRUE, type);
632 }
633 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
634 CPDF_Array* pIdArray,
635 const uint8_t* user_pass,
636 uint32_t user_size,
637 uint32_t type) {
638 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, NULL, 0, FALSE, type);
639 }
640 void CPDF_StandardSecurityHandler::AES256_SetPassword(
641 CPDF_Dictionary* pEncryptDict,
642 const uint8_t* password,
643 uint32_t size,
644 FX_BOOL bOwner,
645 const uint8_t* key) {
646 uint8_t sha[128];
647 CRYPT_SHA1Start(sha);
648 CRYPT_SHA1Update(sha, key, 32);
649 CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5);
650 uint8_t digest[20];
651 CRYPT_SHA1Finish(sha, digest);
652 CFX_ByteString ukey = pEncryptDict->GetStringBy("U");
653 uint8_t digest1[48];
654 if (m_Revision >= 6) {
655 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr,
656 digest1);
657 } else {
658 CRYPT_SHA256Start(sha);
659 CRYPT_SHA256Update(sha, password, size);
660 CRYPT_SHA256Update(sha, digest, 8);
661 if (bOwner) {
662 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength());
663 }
664 CRYPT_SHA256Finish(sha, digest1);
665 }
666 FXSYS_memcpy(digest1 + 32, digest, 16);
667 pEncryptDict->SetAtString(bOwner ? "O" : "U", CFX_ByteString(digest1, 48));
668 if (m_Revision >= 6) {
669 Revision6_Hash(password, size, digest + 8,
670 bOwner ? ukey.raw_str() : nullptr, digest1);
671 } else {
672 CRYPT_SHA256Start(sha);
673 CRYPT_SHA256Update(sha, password, size);
674 CRYPT_SHA256Update(sha, digest + 8, 8);
675 if (bOwner) {
676 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength());
677 }
678 CRYPT_SHA256Finish(sha, digest1);
679 }
680 uint8_t* aes = FX_Alloc(uint8_t, 2048);
681 CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE);
682 uint8_t iv[16];
683 FXSYS_memset(iv, 0, 16);
684 CRYPT_AESSetIV(aes, iv);
685 CRYPT_AESEncrypt(aes, digest1, key, 32);
686 FX_Free(aes);
687 pEncryptDict->SetAtString(bOwner ? "OE" : "UE", CFX_ByteString(digest1, 32));
688 }
689 void CPDF_StandardSecurityHandler::AES256_SetPerms(
690 CPDF_Dictionary* pEncryptDict,
691 uint32_t permissions,
692 FX_BOOL bEncryptMetadata,
693 const uint8_t* key) {
694 uint8_t buf[16];
695 buf[0] = (uint8_t)permissions;
696 buf[1] = (uint8_t)(permissions >> 8);
697 buf[2] = (uint8_t)(permissions >> 16);
698 buf[3] = (uint8_t)(permissions >> 24);
699 buf[4] = 0xff;
700 buf[5] = 0xff;
701 buf[6] = 0xff;
702 buf[7] = 0xff;
703 buf[8] = bEncryptMetadata ? 'T' : 'F';
704 buf[9] = 'a';
705 buf[10] = 'd';
706 buf[11] = 'b';
707 uint8_t* aes = FX_Alloc(uint8_t, 2048);
708 CRYPT_AESSetKey(aes, 16, key, 32, TRUE);
709 uint8_t iv[16], buf1[16];
710 FXSYS_memset(iv, 0, 16);
711 CRYPT_AESSetIV(aes, iv);
712 CRYPT_AESEncrypt(aes, buf1, buf, 16);
713 FX_Free(aes);
714 pEncryptDict->SetAtString("Perms", CFX_ByteString(buf1, 16));
715 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698