| Index: core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp
|
| diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp
|
| index dab9b1f89edc9e6ef55b7aa8f653d1059a7e2cd4..b5e073e83d6dc0c80e31eaaf4d2687cde9531fcc 100644
|
| --- a/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp
|
| +++ b/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp
|
| @@ -6,11 +6,14 @@
|
|
|
| #include "core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.h"
|
|
|
| -#include <time.h>
|
| -
|
| #include "core/include/fdrm/fx_crypt.h"
|
| #include "core/include/fpdfapi/cpdf_parser.h"
|
| +#include "core/include/fpdfapi/cpdf_parser.h"
|
| +#include "core/include/fpdfapi/cpdf_simple_parser.h"
|
| #include "core/include/fpdfapi/fpdf_parser.h"
|
| +#include "core/include/fpdfapi/fpdf_parser.h"
|
| +#include "core/include/fpdfapi/ipdf_security_handler.h"
|
| +#include "core/src/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.h"
|
|
|
| namespace {
|
|
|
| @@ -64,8 +67,6 @@ void CalcEncryptKey(CPDF_Dictionary* pEncrypt,
|
|
|
| } // namespace
|
|
|
| -IPDF_SecurityHandler::~IPDF_SecurityHandler() {}
|
| -
|
| CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler() {
|
| m_Version = 0;
|
| m_Revision = 0;
|
| @@ -78,7 +79,7 @@ CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler() {
|
|
|
| CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler() {}
|
|
|
| -CPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler() {
|
| +IPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler() {
|
| return new CPDF_StandardCryptoHandler;
|
| }
|
|
|
| @@ -708,4 +709,250 @@ void CPDF_StandardSecurityHandler::AES256_SetPerms(
|
| CRYPT_AESEncrypt(aes, buf1, buf, 16);
|
| FX_Free(aes);
|
| pEncryptDict->SetAtString("Perms", CFX_ByteString(buf1, 16));
|
| +=======
|
| + struct PDF_CRYPTOITEM {
|
| + int32_t m_Cipher;
|
| + int32_t m_KeyLen;
|
| + FX_BOOL m_bChecked;
|
| + CPDF_StandardCryptoHandler* m_pCryptoHandler;
|
| + };
|
| +
|
| + void CPDF_StandardCryptoHandler::CryptBlock(
|
| + FX_BOOL bEncrypt, FX_DWORD objnum, FX_DWORD gennum,
|
| + const uint8_t* src_buf, FX_DWORD src_size, uint8_t* dest_buf,
|
| + FX_DWORD& dest_size) {
|
| + if (m_Cipher == FXCIPHER_NONE) {
|
| + FXSYS_memcpy(dest_buf, src_buf, src_size);
|
| + return;
|
| + }
|
| + uint8_t realkey[16];
|
| + int realkeylen = 16;
|
| + if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) {
|
| + uint8_t key1[32];
|
| + FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen);
|
| + key1[m_KeyLen + 0] = (uint8_t)objnum;
|
| + key1[m_KeyLen + 1] = (uint8_t)(objnum >> 8);
|
| + key1[m_KeyLen + 2] = (uint8_t)(objnum >> 16);
|
| + key1[m_KeyLen + 3] = (uint8_t)gennum;
|
| + key1[m_KeyLen + 4] = (uint8_t)(gennum >> 8);
|
| + FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3);
|
| + FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2);
|
| + if (m_Cipher == FXCIPHER_AES) {
|
| + FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
|
| + }
|
| + CRYPT_MD5Generate(key1,
|
| + m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5,
|
| + realkey);
|
| + realkeylen = m_KeyLen + 5;
|
| + if (realkeylen > 16) {
|
| + realkeylen = 16;
|
| + }
|
| + }
|
| + if (m_Cipher == FXCIPHER_AES) {
|
| + CRYPT_AESSetKey(m_pAESContext, 16,
|
| + m_KeyLen == 32 ? m_EncryptKey : realkey, m_KeyLen,
|
| + bEncrypt);
|
| + if (bEncrypt) {
|
| + uint8_t iv[16];
|
| + for (int i = 0; i < 16; i++) {
|
| + iv[i] = (uint8_t)rand();
|
| + }
|
| + CRYPT_AESSetIV(m_pAESContext, iv);
|
| + FXSYS_memcpy(dest_buf, iv, 16);
|
| + int nblocks = src_size / 16;
|
| + CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16);
|
| + uint8_t padding[16];
|
| + FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16);
|
| + FXSYS_memset(padding + src_size % 16, 16 - src_size % 16,
|
| + 16 - src_size % 16);
|
| + CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding,
|
| + 16);
|
| + dest_size = 32 + nblocks * 16;
|
| + } else {
|
| + CRYPT_AESSetIV(m_pAESContext, src_buf);
|
| + CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16);
|
| + dest_size = src_size - 16;
|
| + dest_size -= dest_buf[dest_size - 1];
|
| + }
|
| + } else {
|
| + ASSERT(dest_size == src_size);
|
| + if (dest_buf != src_buf) {
|
| + FXSYS_memcpy(dest_buf, src_buf, src_size);
|
| + }
|
| + CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen);
|
| + }
|
| + }
|
| +
|
| + struct AESCryptContext {
|
| + uint8_t m_Context[2048];
|
| + FX_BOOL m_bIV;
|
| + uint8_t m_Block[16];
|
| + FX_DWORD m_BlockOffset;
|
| + };
|
| +
|
| + void* CPDF_StandardCryptoHandler::CryptStart(FX_DWORD objnum, FX_DWORD gennum,
|
| + FX_BOOL bEncrypt) {
|
| + if (m_Cipher == FXCIPHER_NONE) {
|
| + return this;
|
| + }
|
| + if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) {
|
| + AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
|
| + pContext->m_bIV = TRUE;
|
| + pContext->m_BlockOffset = 0;
|
| + CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt);
|
| + if (bEncrypt) {
|
| + for (int i = 0; i < 16; i++) {
|
| + pContext->m_Block[i] = (uint8_t)rand();
|
| + }
|
| + CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
|
| + }
|
| + return pContext;
|
| + }
|
| + uint8_t key1[48];
|
| + FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen);
|
| + FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3);
|
| + FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2);
|
| + if (m_Cipher == FXCIPHER_AES) {
|
| + FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
|
| + }
|
| + uint8_t realkey[16];
|
| + CRYPT_MD5Generate(
|
| + key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
|
| + int realkeylen = m_KeyLen + 5;
|
| + if (realkeylen > 16) {
|
| + realkeylen = 16;
|
| + }
|
| + if (m_Cipher == FXCIPHER_AES) {
|
| + AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
|
| + pContext->m_bIV = TRUE;
|
| + pContext->m_BlockOffset = 0;
|
| + CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt);
|
| + if (bEncrypt) {
|
| + for (int i = 0; i < 16; i++) {
|
| + pContext->m_Block[i] = (uint8_t)rand();
|
| + }
|
| + CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
|
| + }
|
| + return pContext;
|
| + }
|
| + void* pContext = FX_Alloc(uint8_t, 1040);
|
| + CRYPT_ArcFourSetup(pContext, realkey, realkeylen);
|
| + return pContext;
|
| + }
|
| + FX_BOOL CPDF_StandardCryptoHandler::CryptStream(
|
| + void* context, const uint8_t* src_buf, FX_DWORD src_size,
|
| + CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt) {
|
| + if (!context) {
|
| + return FALSE;
|
| + }
|
| + if (m_Cipher == FXCIPHER_NONE) {
|
| + dest_buf.AppendBlock(src_buf, src_size);
|
| + return TRUE;
|
| + }
|
| + if (m_Cipher == FXCIPHER_RC4) {
|
| + int old_size = dest_buf.GetSize();
|
| + dest_buf.AppendBlock(src_buf, src_size);
|
| + CRYPT_ArcFourCrypt(context, dest_buf.GetBuffer() + old_size, src_size);
|
| + return TRUE;
|
| + }
|
| + AESCryptContext* pContext = (AESCryptContext*)context;
|
| + if (pContext->m_bIV && bEncrypt) {
|
| + dest_buf.AppendBlock(pContext->m_Block, 16);
|
| + pContext->m_bIV = FALSE;
|
| + }
|
| + FX_DWORD src_off = 0;
|
| + FX_DWORD src_left = src_size;
|
| + while (1) {
|
| + FX_DWORD copy_size = 16 - pContext->m_BlockOffset;
|
| + if (copy_size > src_left) {
|
| + copy_size = src_left;
|
| + }
|
| + FXSYS_memcpy(pContext->m_Block + pContext->m_BlockOffset,
|
| + src_buf + src_off, copy_size);
|
| + src_off += copy_size;
|
| + src_left -= copy_size;
|
| + pContext->m_BlockOffset += copy_size;
|
| + if (pContext->m_BlockOffset == 16) {
|
| + if (!bEncrypt && pContext->m_bIV) {
|
| + CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
|
| + pContext->m_bIV = FALSE;
|
| + pContext->m_BlockOffset = 0;
|
| + } else if (src_off < src_size) {
|
| + uint8_t block_buf[16];
|
| + if (bEncrypt) {
|
| + CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block,
|
| + 16);
|
| + } else {
|
| + CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block,
|
| + 16);
|
| + }
|
| + dest_buf.AppendBlock(block_buf, 16);
|
| + pContext->m_BlockOffset = 0;
|
| + }
|
| + }
|
| + if (!src_left) {
|
| + break;
|
| + }
|
| + }
|
| + return TRUE;
|
| + }
|
| + FX_BOOL CPDF_StandardCryptoHandler::CryptFinish(
|
| + void* context, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt) {
|
| + if (!context) {
|
| + return FALSE;
|
| + }
|
| + if (m_Cipher == FXCIPHER_NONE) {
|
| + return TRUE;
|
| + }
|
| + if (m_Cipher == FXCIPHER_RC4) {
|
| + FX_Free(context);
|
| + return TRUE;
|
| + }
|
| + AESCryptContext* pContext = (AESCryptContext*)context;
|
| + if (bEncrypt) {
|
| + uint8_t block_buf[16];
|
| + if (pContext->m_BlockOffset == 16) {
|
| + CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
|
| + dest_buf.AppendBlock(block_buf, 16);
|
| + pContext->m_BlockOffset = 0;
|
| + }
|
| + FXSYS_memset(pContext->m_Block + pContext->m_BlockOffset,
|
| + (uint8_t)(16 - pContext->m_BlockOffset),
|
| + 16 - pContext->m_BlockOffset);
|
| + CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
|
| + dest_buf.AppendBlock(block_buf, 16);
|
| + } else if (pContext->m_BlockOffset == 16) {
|
| + uint8_t block_buf[16];
|
| + CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
|
| + if (block_buf[15] <= 16) {
|
| + dest_buf.AppendBlock(block_buf, 16 - block_buf[15]);
|
| + }
|
| + }
|
| + FX_Free(pContext);
|
| + return TRUE;
|
| + }
|
| + void* CPDF_StandardCryptoHandler::DecryptStart(FX_DWORD objnum,
|
| + FX_DWORD gennum) {
|
| + return CryptStart(objnum, gennum, FALSE);
|
| + }
|
| + FX_DWORD CPDF_StandardCryptoHandler::DecryptGetSize(FX_DWORD src_size) {
|
| + return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size;
|
| + }
|
| +
|
| + FX_BOOL CPDF_StandardCryptoHandler::Init(
|
| + CPDF_Dictionary * pEncryptDict, IPDF_SecurityHandler * pSecurityHandler) {
|
| + const uint8_t* key;
|
| + if (!pSecurityHandler->GetCryptInfo(m_Cipher, key, m_KeyLen)) {
|
| + return FALSE;
|
| + }
|
| + if (m_KeyLen > 32 || m_KeyLen < 0) {
|
| + return FALSE;
|
| + }
|
| + if (m_Cipher != FXCIPHER_NONE) {
|
| + FXSYS_memcpy(m_EncryptKey, key, m_KeyLen);
|
| + }
|
| + if (m_Cipher == FXCIPHER_AES) {
|
| + m_pAESContext = FX_Alloc(uint8_t, 2048);
|
| + }
|
| + return TRUE;
|
| }
|
|
|