| OLD | NEW |
| 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 |
| 11 #include <algorithm> |
| 12 #include <utility> |
| 13 #include <vector> |
| 14 |
| 11 #include "core/fdrm/crypto/fx_crypt.h" | 15 #include "core/fdrm/crypto/fx_crypt.h" |
| 12 #include "core/fpdfapi/parser/cpdf_array.h" | 16 #include "core/fpdfapi/parser/cpdf_array.h" |
| 13 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" | 17 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" |
| 14 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 18 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
| 15 #include "core/fpdfapi/parser/cpdf_object.h" | 19 #include "core/fpdfapi/parser/cpdf_object.h" |
| 16 #include "core/fpdfapi/parser/cpdf_parser.h" | 20 #include "core/fpdfapi/parser/cpdf_parser.h" |
| 21 #include "core/fpdfapi/parser/cpdf_string.h" |
| 17 | 22 |
| 18 namespace { | 23 namespace { |
| 19 | 24 |
| 20 const uint8_t defpasscode[32] = { | 25 const uint8_t defpasscode[32] = { |
| 21 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, | 26 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, |
| 22 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, | 27 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, |
| 23 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a}; | 28 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a}; |
| 24 | 29 |
| 25 void CalcEncryptKey(CPDF_Dictionary* pEncrypt, | 30 void CalcEncryptKey(CPDF_Dictionary* pEncrypt, |
| 26 const uint8_t* password, | 31 const uint8_t* password, |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 } | 568 } |
| 564 CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); | 569 CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); |
| 565 uint8_t tempkey[32]; | 570 uint8_t tempkey[32]; |
| 566 if (m_Revision >= 3) { | 571 if (m_Revision >= 3) { |
| 567 for (uint8_t i = 1; i <= 19; i++) { | 572 for (uint8_t i = 1; i <= 19; i++) { |
| 568 for (int j = 0; j < key_len; j++) | 573 for (int j = 0; j < key_len; j++) |
| 569 tempkey[j] = enckey[j] ^ i; | 574 tempkey[j] = enckey[j] ^ i; |
| 570 CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); | 575 CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); |
| 571 } | 576 } |
| 572 } | 577 } |
| 573 pEncryptDict->SetStringFor("O", CFX_ByteString(passcode, 32)); | 578 pEncryptDict->SetNewFor<CPDF_String>("O", CFX_ByteString(passcode, 32), |
| 579 false); |
| 574 } | 580 } |
| 575 CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, | 581 CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, |
| 576 key_len, false, pIdArray); | 582 key_len, false, pIdArray); |
| 577 if (m_Revision < 3) { | 583 if (m_Revision < 3) { |
| 578 uint8_t tempbuf[32]; | 584 uint8_t tempbuf[32]; |
| 579 FXSYS_memcpy(tempbuf, defpasscode, 32); | 585 FXSYS_memcpy(tempbuf, defpasscode, 32); |
| 580 CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); | 586 CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); |
| 581 pEncryptDict->SetStringFor("U", CFX_ByteString(tempbuf, 32)); | 587 pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(tempbuf, 32), |
| 588 false); |
| 582 } else { | 589 } else { |
| 583 uint8_t md5[100]; | 590 uint8_t md5[100]; |
| 584 CRYPT_MD5Start(md5); | 591 CRYPT_MD5Start(md5); |
| 585 CRYPT_MD5Update(md5, defpasscode, 32); | 592 CRYPT_MD5Update(md5, defpasscode, 32); |
| 586 if (pIdArray) { | 593 if (pIdArray) { |
| 587 CFX_ByteString id = pIdArray->GetStringAt(0); | 594 CFX_ByteString id = pIdArray->GetStringAt(0); |
| 588 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); | 595 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); |
| 589 } | 596 } |
| 590 uint8_t digest[32]; | 597 uint8_t digest[32]; |
| 591 CRYPT_MD5Finish(md5, digest); | 598 CRYPT_MD5Finish(md5, digest); |
| 592 CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); | 599 CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); |
| 593 uint8_t tempkey[32]; | 600 uint8_t tempkey[32]; |
| 594 for (uint8_t i = 1; i <= 19; i++) { | 601 for (uint8_t i = 1; i <= 19; i++) { |
| 595 for (int j = 0; j < key_len; j++) { | 602 for (int j = 0; j < key_len; j++) { |
| 596 tempkey[j] = m_EncryptKey[j] ^ i; | 603 tempkey[j] = m_EncryptKey[j] ^ i; |
| 597 } | 604 } |
| 598 CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); | 605 CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); |
| 599 } | 606 } |
| 600 CRYPT_MD5Generate(digest, 16, digest + 16); | 607 CRYPT_MD5Generate(digest, 16, digest + 16); |
| 601 pEncryptDict->SetStringFor("U", CFX_ByteString(digest, 32)); | 608 pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(digest, 32), |
| 609 false); |
| 602 } | 610 } |
| 603 } | 611 } |
| 604 void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, | 612 void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, |
| 605 CPDF_Array* pIdArray, | 613 CPDF_Array* pIdArray, |
| 606 const uint8_t* user_pass, | 614 const uint8_t* user_pass, |
| 607 uint32_t user_size, | 615 uint32_t user_size, |
| 608 const uint8_t* owner_pass, | 616 const uint8_t* owner_pass, |
| 609 uint32_t owner_size, | 617 uint32_t owner_size, |
| 610 uint32_t type) { | 618 uint32_t type) { |
| 611 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size, | 619 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 638 } else { | 646 } else { |
| 639 CRYPT_SHA256Start(sha); | 647 CRYPT_SHA256Start(sha); |
| 640 CRYPT_SHA256Update(sha, password, size); | 648 CRYPT_SHA256Update(sha, password, size); |
| 641 CRYPT_SHA256Update(sha, digest, 8); | 649 CRYPT_SHA256Update(sha, digest, 8); |
| 642 if (bOwner) { | 650 if (bOwner) { |
| 643 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); | 651 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); |
| 644 } | 652 } |
| 645 CRYPT_SHA256Finish(sha, digest1); | 653 CRYPT_SHA256Finish(sha, digest1); |
| 646 } | 654 } |
| 647 FXSYS_memcpy(digest1 + 32, digest, 16); | 655 FXSYS_memcpy(digest1 + 32, digest, 16); |
| 648 pEncryptDict->SetStringFor(bOwner ? "O" : "U", CFX_ByteString(digest1, 48)); | 656 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", |
| 657 CFX_ByteString(digest1, 48), false); |
| 649 if (m_Revision >= 6) { | 658 if (m_Revision >= 6) { |
| 650 Revision6_Hash(password, size, digest + 8, | 659 Revision6_Hash(password, size, digest + 8, |
| 651 bOwner ? ukey.raw_str() : nullptr, digest1); | 660 bOwner ? ukey.raw_str() : nullptr, digest1); |
| 652 } else { | 661 } else { |
| 653 CRYPT_SHA256Start(sha); | 662 CRYPT_SHA256Start(sha); |
| 654 CRYPT_SHA256Update(sha, password, size); | 663 CRYPT_SHA256Update(sha, password, size); |
| 655 CRYPT_SHA256Update(sha, digest + 8, 8); | 664 CRYPT_SHA256Update(sha, digest + 8, 8); |
| 656 if (bOwner) { | 665 if (bOwner) { |
| 657 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); | 666 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); |
| 658 } | 667 } |
| 659 CRYPT_SHA256Finish(sha, digest1); | 668 CRYPT_SHA256Finish(sha, digest1); |
| 660 } | 669 } |
| 661 uint8_t* aes = FX_Alloc(uint8_t, 2048); | 670 uint8_t* aes = FX_Alloc(uint8_t, 2048); |
| 662 CRYPT_AESSetKey(aes, 16, digest1, 32, true); | 671 CRYPT_AESSetKey(aes, 16, digest1, 32, true); |
| 663 uint8_t iv[16]; | 672 uint8_t iv[16]; |
| 664 FXSYS_memset(iv, 0, 16); | 673 FXSYS_memset(iv, 0, 16); |
| 665 CRYPT_AESSetIV(aes, iv); | 674 CRYPT_AESSetIV(aes, iv); |
| 666 CRYPT_AESEncrypt(aes, digest1, key, 32); | 675 CRYPT_AESEncrypt(aes, digest1, key, 32); |
| 667 FX_Free(aes); | 676 FX_Free(aes); |
| 668 pEncryptDict->SetStringFor(bOwner ? "OE" : "UE", CFX_ByteString(digest1, 32)); | 677 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", |
| 678 CFX_ByteString(digest1, 32), false); |
| 669 } | 679 } |
| 680 |
| 670 void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, | 681 void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, |
| 671 uint32_t permissions, | 682 uint32_t permissions, |
| 672 bool bEncryptMetadata, | 683 bool bEncryptMetadata, |
| 673 const uint8_t* key) { | 684 const uint8_t* key) { |
| 674 uint8_t buf[16]; | 685 uint8_t buf[16]; |
| 675 buf[0] = (uint8_t)permissions; | 686 buf[0] = (uint8_t)permissions; |
| 676 buf[1] = (uint8_t)(permissions >> 8); | 687 buf[1] = (uint8_t)(permissions >> 8); |
| 677 buf[2] = (uint8_t)(permissions >> 16); | 688 buf[2] = (uint8_t)(permissions >> 16); |
| 678 buf[3] = (uint8_t)(permissions >> 24); | 689 buf[3] = (uint8_t)(permissions >> 24); |
| 679 buf[4] = 0xff; | 690 buf[4] = 0xff; |
| 680 buf[5] = 0xff; | 691 buf[5] = 0xff; |
| 681 buf[6] = 0xff; | 692 buf[6] = 0xff; |
| 682 buf[7] = 0xff; | 693 buf[7] = 0xff; |
| 683 buf[8] = bEncryptMetadata ? 'T' : 'F'; | 694 buf[8] = bEncryptMetadata ? 'T' : 'F'; |
| 684 buf[9] = 'a'; | 695 buf[9] = 'a'; |
| 685 buf[10] = 'd'; | 696 buf[10] = 'd'; |
| 686 buf[11] = 'b'; | 697 buf[11] = 'b'; |
| 687 uint8_t* aes = FX_Alloc(uint8_t, 2048); | 698 uint8_t* aes = FX_Alloc(uint8_t, 2048); |
| 688 CRYPT_AESSetKey(aes, 16, key, 32, true); | 699 CRYPT_AESSetKey(aes, 16, key, 32, true); |
| 689 uint8_t iv[16], buf1[16]; | 700 uint8_t iv[16], buf1[16]; |
| 690 FXSYS_memset(iv, 0, 16); | 701 FXSYS_memset(iv, 0, 16); |
| 691 CRYPT_AESSetIV(aes, iv); | 702 CRYPT_AESSetIV(aes, iv); |
| 692 CRYPT_AESEncrypt(aes, buf1, buf, 16); | 703 CRYPT_AESEncrypt(aes, buf1, buf, 16); |
| 693 FX_Free(aes); | 704 FX_Free(aes); |
| 694 pEncryptDict->SetStringFor("Perms", CFX_ByteString(buf1, 16)); | 705 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), |
| 706 false); |
| 695 } | 707 } |
| OLD | NEW |