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

Side by Side Diff: core/fpdfapi/parser/cpdf_security_handler.cpp

Issue 2577223002: Better tests for password protected documents. (Closed)
Patch Set: revert pdfium_test Created 4 years 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
« no previous file with comments | « core/fdrm/crypto/fx_crypt_unittest.cpp ('k') | xfa/fxfa/DEPS » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/fpdfapi/parser/cpdf_security_handler.h" 7 #include "core/fpdfapi/parser/cpdf_security_handler.h"
8 8
9 #include <time.h> 9 #include <time.h>
10 10
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 uint64_t ret = 0; 221 uint64_t ret = 0;
222 for (int i = 0; i < 4; ++i) { 222 for (int i = 0; i < 4; ++i) {
223 uint32_t value; 223 uint32_t value;
224 FX_GET_32WORD(value, data, 4 * i); 224 FX_GET_32WORD(value, data, 4 * i);
225 ret <<= 32; 225 ret <<= 32;
226 ret |= value; 226 ret |= value;
227 ret %= 3; 227 ret %= 3;
228 } 228 }
229 return (int)ret; 229 return (int)ret;
230 } 230 }
231
231 void Revision6_Hash(const uint8_t* password, 232 void Revision6_Hash(const uint8_t* password,
232 uint32_t size, 233 uint32_t size,
233 const uint8_t* salt, 234 const uint8_t* salt,
234 const uint8_t* vector, 235 const uint8_t* vector,
235 uint8_t* hash) { 236 uint8_t* hash) {
236 int iBlockSize = 32; 237 CRYPT_sha256_context sha;
237 uint8_t sha[128]; 238 CRYPT_SHA256Start(&sha);
238 CRYPT_SHA256Start(sha); 239 CRYPT_SHA256Update(&sha, password, size);
239 CRYPT_SHA256Update(sha, password, size); 240 CRYPT_SHA256Update(&sha, salt, 8);
240 CRYPT_SHA256Update(sha, salt, 8); 241 if (vector)
241 if (vector) { 242 CRYPT_SHA256Update(&sha, vector, 48);
242 CRYPT_SHA256Update(sha, vector, 48); 243
243 }
244 uint8_t digest[32]; 244 uint8_t digest[32];
245 CRYPT_SHA256Finish(sha, digest); 245 CRYPT_SHA256Finish(&sha, digest);
246
246 CFX_ByteTextBuf buf; 247 CFX_ByteTextBuf buf;
247 uint8_t* input = digest; 248 uint8_t* input = digest;
248 uint8_t* key = input; 249 uint8_t* key = input;
249 uint8_t* iv = input + 16; 250 uint8_t* iv = input + 16;
250 uint8_t* E = buf.GetBuffer(); 251 uint8_t* E = buf.GetBuffer();
251 int iBufLen = buf.GetLength(); 252 int iBufLen = buf.GetLength();
252 CFX_ByteTextBuf interDigest; 253 CFX_ByteTextBuf interDigest;
253 int i = 0; 254 int i = 0;
255 int iBlockSize = 32;
254 uint8_t* aes = FX_Alloc(uint8_t, 2048); 256 uint8_t* aes = FX_Alloc(uint8_t, 2048);
255 while (i < 64 || i < E[iBufLen - 1] + 32) { 257 while (i < 64 || i < E[iBufLen - 1] + 32) {
256 int iRoundSize = size + iBlockSize; 258 int iRoundSize = size + iBlockSize;
257 if (vector) { 259 if (vector) {
258 iRoundSize += 48; 260 iRoundSize += 48;
259 } 261 }
260 iBufLen = iRoundSize * 64; 262 iBufLen = iRoundSize * 64;
261 buf.EstimateSize(iBufLen); 263 buf.EstimateSize(iBufLen);
262 E = buf.GetBuffer(); 264 E = buf.GetBuffer();
263 CFX_ByteTextBuf content; 265 CFX_ByteTextBuf content;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 } 299 }
298 key = input; 300 key = input;
299 iv = input + 16; 301 iv = input + 16;
300 ++i; 302 ++i;
301 } 303 }
302 FX_Free(aes); 304 FX_Free(aes);
303 if (hash) { 305 if (hash) {
304 FXSYS_memcpy(hash, input, 32); 306 FXSYS_memcpy(hash, input, 32);
305 } 307 }
306 } 308 }
309
307 bool CPDF_SecurityHandler::AES256_CheckPassword(const uint8_t* password, 310 bool CPDF_SecurityHandler::AES256_CheckPassword(const uint8_t* password,
308 uint32_t size, 311 uint32_t size,
309 bool bOwner, 312 bool bOwner,
310 uint8_t* key) { 313 uint8_t* key) {
311 CFX_ByteString okey = 314 if (!m_pEncryptDict)
312 m_pEncryptDict ? m_pEncryptDict->GetStringFor("O") : CFX_ByteString();
313 if (okey.GetLength() < 48) {
314 return false; 315 return false;
315 } 316
316 CFX_ByteString ukey = 317 CFX_ByteString okey = m_pEncryptDict->GetStringFor("O");
317 m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString(); 318 if (okey.GetLength() < 48)
318 if (ukey.GetLength() < 48) {
319 return false; 319 return false;
320 } 320
321 const uint8_t* pkey = (bOwner ? okey : ukey).raw_str(); 321 CFX_ByteString ukey = m_pEncryptDict->GetStringFor("U");
322 uint8_t sha[128]; 322 if (ukey.GetLength() < 48)
323 return false;
324
325 const uint8_t* pkey = bOwner ? okey.raw_str() : ukey.raw_str();
326 CRYPT_sha256_context sha;
323 uint8_t digest[32]; 327 uint8_t digest[32];
324 if (m_Revision >= 6) { 328 if (m_Revision >= 6) {
325 Revision6_Hash(password, size, (const uint8_t*)pkey + 32, 329 Revision6_Hash(password, size, (const uint8_t*)pkey + 32,
326 bOwner ? ukey.raw_str() : nullptr, digest); 330 bOwner ? ukey.raw_str() : nullptr, digest);
327 } else { 331 } else {
328 CRYPT_SHA256Start(sha); 332 CRYPT_SHA256Start(&sha);
329 CRYPT_SHA256Update(sha, password, size); 333 CRYPT_SHA256Update(&sha, password, size);
330 CRYPT_SHA256Update(sha, pkey + 32, 8); 334 CRYPT_SHA256Update(&sha, pkey + 32, 8);
331 if (bOwner) { 335 if (bOwner)
332 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); 336 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48);
333 } 337
334 CRYPT_SHA256Finish(sha, digest); 338 CRYPT_SHA256Finish(&sha, digest);
335 } 339 }
336 if (FXSYS_memcmp(digest, pkey, 32) != 0) { 340 if (FXSYS_memcmp(digest, pkey, 32) != 0)
337 return false; 341 return false;
338 } 342
339 if (!key) { 343 if (!key)
340 return true; 344 return true;
341 } 345
342 if (m_Revision >= 6) { 346 if (m_Revision >= 6) {
343 Revision6_Hash(password, size, (const uint8_t*)pkey + 40, 347 Revision6_Hash(password, size, (const uint8_t*)pkey + 40,
344 bOwner ? ukey.raw_str() : nullptr, digest); 348 bOwner ? ukey.raw_str() : nullptr, digest);
345 } else { 349 } else {
346 CRYPT_SHA256Start(sha); 350 CRYPT_SHA256Start(&sha);
347 CRYPT_SHA256Update(sha, password, size); 351 CRYPT_SHA256Update(&sha, password, size);
348 CRYPT_SHA256Update(sha, pkey + 40, 8); 352 CRYPT_SHA256Update(&sha, pkey + 40, 8);
349 if (bOwner) { 353 if (bOwner)
350 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); 354 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48);
351 } 355
352 CRYPT_SHA256Finish(sha, digest); 356 CRYPT_SHA256Finish(&sha, digest);
353 } 357 }
354 CFX_ByteString ekey = m_pEncryptDict 358 CFX_ByteString ekey = m_pEncryptDict
355 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE") 359 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE")
356 : CFX_ByteString(); 360 : CFX_ByteString();
357 if (ekey.GetLength() < 32) 361 if (ekey.GetLength() < 32)
358 return false; 362 return false;
359 363
360 std::vector<uint8_t> aes(2048); 364 std::vector<uint8_t> aes(2048);
361 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false); 365 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false);
362 uint8_t iv[16]; 366 uint8_t iv[16];
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 int cipher = 0, key_len = 0; 530 int cipher = 0, key_len = 0;
527 if (!LoadDict(pEncryptDict, type, cipher, key_len)) { 531 if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
528 return; 532 return;
529 } 533 }
530 if (bDefault && (!owner_pass || owner_size == 0)) { 534 if (bDefault && (!owner_pass || owner_size == 0)) {
531 owner_pass = user_pass; 535 owner_pass = user_pass;
532 owner_size = user_size; 536 owner_size = user_size;
533 } 537 }
534 if (m_Revision >= 5) { 538 if (m_Revision >= 5) {
535 int t = (int)time(nullptr); 539 int t = (int)time(nullptr);
536 uint8_t sha[128]; 540 CRYPT_sha256_context sha;
537 CRYPT_SHA256Start(sha); 541 CRYPT_SHA256Start(&sha);
538 CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); 542 CRYPT_SHA256Update(&sha, (uint8_t*)&t, sizeof t);
539 CRYPT_SHA256Update(sha, m_EncryptKey, 32); 543 CRYPT_SHA256Update(&sha, m_EncryptKey, 32);
540 CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); 544 CRYPT_SHA256Update(&sha, (uint8_t*)"there", 5);
541 CRYPT_SHA256Finish(sha, m_EncryptKey); 545 CRYPT_SHA256Finish(&sha, m_EncryptKey);
542 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey); 546 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey);
543 if (bDefault) { 547 if (bDefault) {
544 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true, 548 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true,
545 m_EncryptKey); 549 m_EncryptKey);
546 AES256_SetPerms(pEncryptDict, m_Permissions, 550 AES256_SetPerms(pEncryptDict, m_Permissions,
547 pEncryptDict->GetBooleanFor("EncryptMetadata", true), 551 pEncryptDict->GetBooleanFor("EncryptMetadata", true),
548 m_EncryptKey); 552 m_EncryptKey);
549 } 553 }
550 return; 554 return;
551 } 555 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 uint32_t user_size, 629 uint32_t user_size,
626 uint32_t type) { 630 uint32_t type) {
627 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false, 631 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false,
628 type); 632 type);
629 } 633 }
630 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, 634 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict,
631 const uint8_t* password, 635 const uint8_t* password,
632 uint32_t size, 636 uint32_t size,
633 bool bOwner, 637 bool bOwner,
634 const uint8_t* key) { 638 const uint8_t* key) {
635 uint8_t sha[128]; 639 CRYPT_sha1_context sha;
636 CRYPT_SHA1Start(sha); 640 CRYPT_SHA1Start(&sha);
637 CRYPT_SHA1Update(sha, key, 32); 641 CRYPT_SHA1Update(&sha, key, 32);
638 CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5); 642 CRYPT_SHA1Update(&sha, (uint8_t*)"hello", 5);
643
639 uint8_t digest[20]; 644 uint8_t digest[20];
640 CRYPT_SHA1Finish(sha, digest); 645 CRYPT_SHA1Finish(&sha, digest);
646
641 CFX_ByteString ukey = pEncryptDict->GetStringFor("U"); 647 CFX_ByteString ukey = pEncryptDict->GetStringFor("U");
648 CRYPT_sha256_context sha2;
642 uint8_t digest1[48]; 649 uint8_t digest1[48];
643 if (m_Revision >= 6) { 650 if (m_Revision >= 6) {
644 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr, 651 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr,
645 digest1); 652 digest1);
646 } else { 653 } else {
647 CRYPT_SHA256Start(sha); 654 CRYPT_SHA256Start(&sha2);
648 CRYPT_SHA256Update(sha, password, size); 655 CRYPT_SHA256Update(&sha2, password, size);
649 CRYPT_SHA256Update(sha, digest, 8); 656 CRYPT_SHA256Update(&sha2, digest, 8);
650 if (bOwner) { 657 if (bOwner) {
651 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); 658 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength());
652 } 659 }
653 CRYPT_SHA256Finish(sha, digest1); 660 CRYPT_SHA256Finish(&sha2, digest1);
654 } 661 }
655 FXSYS_memcpy(digest1 + 32, digest, 16); 662 FXSYS_memcpy(digest1 + 32, digest, 16);
656 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", 663 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U",
657 CFX_ByteString(digest1, 48), false); 664 CFX_ByteString(digest1, 48), false);
658 if (m_Revision >= 6) { 665 if (m_Revision >= 6) {
659 Revision6_Hash(password, size, digest + 8, 666 Revision6_Hash(password, size, digest + 8,
660 bOwner ? ukey.raw_str() : nullptr, digest1); 667 bOwner ? ukey.raw_str() : nullptr, digest1);
661 } else { 668 } else {
662 CRYPT_SHA256Start(sha); 669 CRYPT_SHA256Start(&sha2);
663 CRYPT_SHA256Update(sha, password, size); 670 CRYPT_SHA256Update(&sha2, password, size);
664 CRYPT_SHA256Update(sha, digest + 8, 8); 671 CRYPT_SHA256Update(&sha2, digest + 8, 8);
665 if (bOwner) { 672 if (bOwner) {
666 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); 673 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength());
667 } 674 }
668 CRYPT_SHA256Finish(sha, digest1); 675 CRYPT_SHA256Finish(&sha2, digest1);
669 } 676 }
670 uint8_t* aes = FX_Alloc(uint8_t, 2048); 677 uint8_t* aes = FX_Alloc(uint8_t, 2048);
671 CRYPT_AESSetKey(aes, 16, digest1, 32, true); 678 CRYPT_AESSetKey(aes, 16, digest1, 32, true);
672 uint8_t iv[16]; 679 uint8_t iv[16];
673 FXSYS_memset(iv, 0, 16); 680 FXSYS_memset(iv, 0, 16);
674 CRYPT_AESSetIV(aes, iv); 681 CRYPT_AESSetIV(aes, iv);
675 CRYPT_AESEncrypt(aes, digest1, key, 32); 682 CRYPT_AESEncrypt(aes, digest1, key, 32);
676 FX_Free(aes); 683 FX_Free(aes);
677 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", 684 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE",
678 CFX_ByteString(digest1, 32), false); 685 CFX_ByteString(digest1, 32), false);
(...skipping 19 matching lines...) Expand all
698 uint8_t* aes = FX_Alloc(uint8_t, 2048); 705 uint8_t* aes = FX_Alloc(uint8_t, 2048);
699 CRYPT_AESSetKey(aes, 16, key, 32, true); 706 CRYPT_AESSetKey(aes, 16, key, 32, true);
700 uint8_t iv[16], buf1[16]; 707 uint8_t iv[16], buf1[16];
701 FXSYS_memset(iv, 0, 16); 708 FXSYS_memset(iv, 0, 16);
702 CRYPT_AESSetIV(aes, iv); 709 CRYPT_AESSetIV(aes, iv);
703 CRYPT_AESEncrypt(aes, buf1, buf, 16); 710 CRYPT_AESEncrypt(aes, buf1, buf, 16);
704 FX_Free(aes); 711 FX_Free(aes);
705 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), 712 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16),
706 false); 713 false);
707 } 714 }
OLDNEW
« no previous file with comments | « core/fdrm/crypto/fx_crypt_unittest.cpp ('k') | xfa/fxfa/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698