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