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

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

Issue 2577223002: Better tests for password protected documents. (Closed)
Patch Set: Fix API and add tests 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
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 m_pEncryptDict ? m_pEncryptDict->GetStringFor("O") : CFX_ByteString(); 314 m_pEncryptDict ? m_pEncryptDict->GetStringFor("O") : CFX_ByteString();
313 if (okey.GetLength() < 48) { 315 if (okey.GetLength() < 48) {
314 return false; 316 return false;
315 } 317 }
316 CFX_ByteString ukey = 318 CFX_ByteString ukey =
317 m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString(); 319 m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString();
318 if (ukey.GetLength() < 48) { 320 if (ukey.GetLength() < 48) {
319 return false; 321 return false;
320 } 322 }
321 const uint8_t* pkey = (bOwner ? okey : ukey).raw_str(); 323 const uint8_t* pkey = (bOwner ? okey : ukey).raw_str();
322 uint8_t sha[128]; 324 CRYPT_sha256_context sha;
323 uint8_t digest[32]; 325 uint8_t digest[32];
324 if (m_Revision >= 6) { 326 if (m_Revision >= 6) {
325 Revision6_Hash(password, size, (const uint8_t*)pkey + 32, 327 Revision6_Hash(password, size, (const uint8_t*)pkey + 32,
326 bOwner ? ukey.raw_str() : nullptr, digest); 328 bOwner ? ukey.raw_str() : nullptr, digest);
327 } else { 329 } else {
328 CRYPT_SHA256Start(sha); 330 CRYPT_SHA256Start(&sha);
329 CRYPT_SHA256Update(sha, password, size); 331 CRYPT_SHA256Update(&sha, password, size);
330 CRYPT_SHA256Update(sha, pkey + 32, 8); 332 CRYPT_SHA256Update(&sha, pkey + 32, 8);
331 if (bOwner) { 333 if (bOwner)
332 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); 334 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48);
333 } 335
334 CRYPT_SHA256Finish(sha, digest); 336 CRYPT_SHA256Finish(&sha, digest);
335 } 337 }
336 if (FXSYS_memcmp(digest, pkey, 32) != 0) { 338 if (FXSYS_memcmp(digest, pkey, 32) != 0)
337 return false; 339 return false;
338 } 340
339 if (!key) { 341 if (!key)
340 return true; 342 return true;
341 } 343
342 if (m_Revision >= 6) { 344 if (m_Revision >= 6) {
343 Revision6_Hash(password, size, (const uint8_t*)pkey + 40, 345 Revision6_Hash(password, size, (const uint8_t*)pkey + 40,
344 bOwner ? ukey.raw_str() : nullptr, digest); 346 bOwner ? ukey.raw_str() : nullptr, digest);
345 } else { 347 } else {
346 CRYPT_SHA256Start(sha); 348 CRYPT_SHA256Start(&sha);
347 CRYPT_SHA256Update(sha, password, size); 349 CRYPT_SHA256Update(&sha, password, size);
348 CRYPT_SHA256Update(sha, pkey + 40, 8); 350 CRYPT_SHA256Update(&sha, pkey + 40, 8);
349 if (bOwner) { 351 if (bOwner)
350 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); 352 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48);
351 } 353
352 CRYPT_SHA256Finish(sha, digest); 354 CRYPT_SHA256Finish(&sha, digest);
353 } 355 }
354 CFX_ByteString ekey = m_pEncryptDict 356 CFX_ByteString ekey = m_pEncryptDict
355 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE") 357 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE")
356 : CFX_ByteString(); 358 : CFX_ByteString();
357 if (ekey.GetLength() < 32) 359 if (ekey.GetLength() < 32)
358 return false; 360 return false;
359 361
360 std::vector<uint8_t> aes(2048); 362 std::vector<uint8_t> aes(2048);
361 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false); 363 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false);
362 uint8_t iv[16]; 364 uint8_t iv[16];
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 int cipher = 0, key_len = 0; 528 int cipher = 0, key_len = 0;
527 if (!LoadDict(pEncryptDict, type, cipher, key_len)) { 529 if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
528 return; 530 return;
529 } 531 }
530 if (bDefault && (!owner_pass || owner_size == 0)) { 532 if (bDefault && (!owner_pass || owner_size == 0)) {
531 owner_pass = user_pass; 533 owner_pass = user_pass;
532 owner_size = user_size; 534 owner_size = user_size;
533 } 535 }
534 if (m_Revision >= 5) { 536 if (m_Revision >= 5) {
535 int t = (int)time(nullptr); 537 int t = (int)time(nullptr);
536 uint8_t sha[128]; 538 CRYPT_sha256_context sha;
537 CRYPT_SHA256Start(sha); 539 CRYPT_SHA256Start(&sha);
538 CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); 540 CRYPT_SHA256Update(&sha, (uint8_t*)&t, sizeof t);
539 CRYPT_SHA256Update(sha, m_EncryptKey, 32); 541 CRYPT_SHA256Update(&sha, m_EncryptKey, 32);
540 CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); 542 CRYPT_SHA256Update(&sha, (uint8_t*)"there", 5);
541 CRYPT_SHA256Finish(sha, m_EncryptKey); 543 CRYPT_SHA256Finish(&sha, m_EncryptKey);
542 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey); 544 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey);
543 if (bDefault) { 545 if (bDefault) {
544 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true, 546 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true,
545 m_EncryptKey); 547 m_EncryptKey);
546 AES256_SetPerms(pEncryptDict, m_Permissions, 548 AES256_SetPerms(pEncryptDict, m_Permissions,
547 pEncryptDict->GetBooleanFor("EncryptMetadata", true), 549 pEncryptDict->GetBooleanFor("EncryptMetadata", true),
548 m_EncryptKey); 550 m_EncryptKey);
549 } 551 }
550 return; 552 return;
551 } 553 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 uint32_t user_size, 627 uint32_t user_size,
626 uint32_t type) { 628 uint32_t type) {
627 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false, 629 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false,
628 type); 630 type);
629 } 631 }
630 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, 632 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict,
631 const uint8_t* password, 633 const uint8_t* password,
632 uint32_t size, 634 uint32_t size,
633 bool bOwner, 635 bool bOwner,
634 const uint8_t* key) { 636 const uint8_t* key) {
635 uint8_t sha[128]; 637 CRYPT_sha1_context sha;
636 CRYPT_SHA1Start(sha); 638 CRYPT_SHA1Start(&sha);
637 CRYPT_SHA1Update(sha, key, 32); 639 CRYPT_SHA1Update(&sha, key, 32);
638 CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5); 640 CRYPT_SHA1Update(&sha, (uint8_t*)"hello", 5);
641
639 uint8_t digest[20]; 642 uint8_t digest[20];
640 CRYPT_SHA1Finish(sha, digest); 643 CRYPT_SHA1Finish(&sha, digest);
644
641 CFX_ByteString ukey = pEncryptDict->GetStringFor("U"); 645 CFX_ByteString ukey = pEncryptDict->GetStringFor("U");
646 CRYPT_sha256_context sha2;
642 uint8_t digest1[48]; 647 uint8_t digest1[48];
643 if (m_Revision >= 6) { 648 if (m_Revision >= 6) {
644 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr, 649 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr,
645 digest1); 650 digest1);
646 } else { 651 } else {
647 CRYPT_SHA256Start(sha); 652 CRYPT_SHA256Start(&sha2);
648 CRYPT_SHA256Update(sha, password, size); 653 CRYPT_SHA256Update(&sha2, password, size);
649 CRYPT_SHA256Update(sha, digest, 8); 654 CRYPT_SHA256Update(&sha2, digest, 8);
650 if (bOwner) { 655 if (bOwner) {
651 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); 656 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength());
652 } 657 }
653 CRYPT_SHA256Finish(sha, digest1); 658 CRYPT_SHA256Finish(&sha2, digest1);
654 } 659 }
655 FXSYS_memcpy(digest1 + 32, digest, 16); 660 FXSYS_memcpy(digest1 + 32, digest, 16);
656 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", 661 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U",
657 CFX_ByteString(digest1, 48), false); 662 CFX_ByteString(digest1, 48), false);
658 if (m_Revision >= 6) { 663 if (m_Revision >= 6) {
659 Revision6_Hash(password, size, digest + 8, 664 Revision6_Hash(password, size, digest + 8,
660 bOwner ? ukey.raw_str() : nullptr, digest1); 665 bOwner ? ukey.raw_str() : nullptr, digest1);
661 } else { 666 } else {
662 CRYPT_SHA256Start(sha); 667 CRYPT_SHA256Start(&sha2);
663 CRYPT_SHA256Update(sha, password, size); 668 CRYPT_SHA256Update(&sha2, password, size);
664 CRYPT_SHA256Update(sha, digest + 8, 8); 669 CRYPT_SHA256Update(&sha2, digest + 8, 8);
665 if (bOwner) { 670 if (bOwner) {
666 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); 671 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength());
667 } 672 }
668 CRYPT_SHA256Finish(sha, digest1); 673 CRYPT_SHA256Finish(&sha2, digest1);
669 } 674 }
670 uint8_t* aes = FX_Alloc(uint8_t, 2048); 675 uint8_t* aes = FX_Alloc(uint8_t, 2048);
671 CRYPT_AESSetKey(aes, 16, digest1, 32, true); 676 CRYPT_AESSetKey(aes, 16, digest1, 32, true);
672 uint8_t iv[16]; 677 uint8_t iv[16];
673 FXSYS_memset(iv, 0, 16); 678 FXSYS_memset(iv, 0, 16);
674 CRYPT_AESSetIV(aes, iv); 679 CRYPT_AESSetIV(aes, iv);
675 CRYPT_AESEncrypt(aes, digest1, key, 32); 680 CRYPT_AESEncrypt(aes, digest1, key, 32);
676 FX_Free(aes); 681 FX_Free(aes);
677 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", 682 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE",
678 CFX_ByteString(digest1, 32), false); 683 CFX_ByteString(digest1, 32), false);
(...skipping 19 matching lines...) Expand all
698 uint8_t* aes = FX_Alloc(uint8_t, 2048); 703 uint8_t* aes = FX_Alloc(uint8_t, 2048);
699 CRYPT_AESSetKey(aes, 16, key, 32, true); 704 CRYPT_AESSetKey(aes, 16, key, 32, true);
700 uint8_t iv[16], buf1[16]; 705 uint8_t iv[16], buf1[16];
701 FXSYS_memset(iv, 0, 16); 706 FXSYS_memset(iv, 0, 16);
702 CRYPT_AESSetIV(aes, iv); 707 CRYPT_AESSetIV(aes, iv);
703 CRYPT_AESEncrypt(aes, buf1, buf, 16); 708 CRYPT_AESEncrypt(aes, buf1, buf, 16);
704 FX_Free(aes); 709 FX_Free(aes);
705 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), 710 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16),
706 false); 711 false);
707 } 712 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698