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; |
} |