summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/edit/cpdf_creator.cpp1
-rw-r--r--core/fpdfapi/parser/cpdf_crypto_handler.cpp68
-rw-r--r--core/fpdfapi/parser/cpdf_crypto_handler.h6
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_security_handler.cpp61
-rw-r--r--core/fpdfapi/parser/cpdf_security_handler.h16
6 files changed, 65 insertions, 90 deletions
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index d6384059d1..eecf37b981 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -807,7 +807,6 @@ void CPDF_Creator::InitID() {
m_pSecurityHandler = pdfium::MakeUnique<CPDF_SecurityHandler>();
m_pSecurityHandler->OnCreate(m_pEncryptDict.Get(), m_pIDArray.get(),
user_pass, flag);
- m_pSecurityHandler->InitCryptoHandler();
m_bSecurityChanged = true;
}
}
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.cpp b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
index 441ca8000d..e8f0265ae4 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -8,6 +8,7 @@
#include <time.h>
+#include <algorithm>
#include <stack>
#include <utility>
@@ -278,56 +279,6 @@ uint32_t CPDF_CryptoHandler::DecryptGetSize(uint32_t src_size) {
return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size;
}
-bool CPDF_CryptoHandler::Init(CPDF_Dictionary* pEncryptDict,
- CPDF_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)
- memcpy(m_EncryptKey, key, m_KeyLen);
-
- if (m_Cipher == FXCIPHER_AES)
- m_pAESContext.reset(FX_Alloc(CRYPT_aes_context, 1));
-
- return true;
-}
-
-bool CPDF_CryptoHandler::Init(int cipher, const uint8_t* key, int keylen) {
- if (cipher == FXCIPHER_AES) {
- switch (keylen) {
- case 16:
- case 24:
- case 32:
- break;
- default:
- return false;
- }
- } else if (cipher == FXCIPHER_AES2) {
- if (keylen != 32) {
- return false;
- }
- } else if (cipher == FXCIPHER_RC4) {
- if (keylen < 5 || keylen > 16) {
- return false;
- }
- } else {
- if (keylen > 32) {
- keylen = 32;
- }
- }
- m_Cipher = cipher;
- m_KeyLen = keylen;
- memcpy(m_EncryptKey, key, keylen);
- if (m_Cipher == FXCIPHER_AES)
- m_pAESContext.reset(FX_Alloc(CRYPT_aes_context, 1));
-
- return true;
-}
-
bool CPDF_CryptoHandler::IsCipherAES() const {
return m_Cipher == FXCIPHER_AES;
}
@@ -444,8 +395,21 @@ bool CPDF_CryptoHandler::EncryptContent(uint32_t objnum,
return true;
}
-CPDF_CryptoHandler::CPDF_CryptoHandler()
- : m_KeyLen(0), m_Cipher(FXCIPHER_NONE) {}
+CPDF_CryptoHandler::CPDF_CryptoHandler(int cipher,
+ const uint8_t* key,
+ int keylen)
+ : m_KeyLen(std::min(keylen, 32)), m_Cipher(cipher) {
+ ASSERT(cipher != FXCIPHER_AES || keylen == 16 || keylen == 24 ||
+ keylen == 32);
+ ASSERT(cipher != FXCIPHER_AES2 || keylen == 32);
+ ASSERT(cipher != FXCIPHER_RC4 || (keylen >= 5 && keylen <= 16));
+
+ if (m_Cipher != FXCIPHER_NONE)
+ memcpy(m_EncryptKey, key, m_KeyLen);
+
+ if (m_Cipher == FXCIPHER_AES)
+ m_pAESContext.reset(FX_Alloc(CRYPT_aes_context, 1));
+}
CPDF_CryptoHandler::~CPDF_CryptoHandler() {}
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.h b/core/fpdfapi/parser/cpdf_crypto_handler.h
index 7175088de4..32eeaef4c9 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.h
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.h
@@ -22,14 +22,11 @@ class CPDF_SecurityHandler;
class CPDF_CryptoHandler {
public:
- CPDF_CryptoHandler();
+ CPDF_CryptoHandler(int cipher, const uint8_t* key, int keylen);
~CPDF_CryptoHandler();
static bool IsSignatureDictionary(const CPDF_Dictionary* dictionary);
- bool Init(CPDF_Dictionary* pEncryptDict,
- CPDF_SecurityHandler* pSecurityHandler);
-
std::unique_ptr<CPDF_Object> DecryptObjectTree(
std::unique_ptr<CPDF_Object> object);
@@ -44,7 +41,6 @@ class CPDF_CryptoHandler {
uint8_t* dest_buf,
uint32_t& dest_size);
- bool Init(int cipher, const uint8_t* key, int keylen);
bool IsCipherAES() const;
private:
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index a1b8a2deba..02cba64541 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -311,9 +311,6 @@ CPDF_Parser::Error CPDF_Parser::SetEncryptHandler() {
m_Password))
return PASSWORD_ERROR;
- if (!pSecurityHandler->InitCryptoHandler())
- return HANDLER_ERROR;
-
m_pSecurityHandler = std::move(pSecurityHandler);
}
return SUCCESS;
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index 9c79b9389b..4a33de116f 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -70,6 +70,22 @@ void CalcEncryptKey(CPDF_Dictionary* pEncrypt,
memcpy(key, digest, copy_len);
}
+bool IsValidKeyLengthForCipher(int cipher, int keylen) {
+ switch (cipher) {
+ case FXCIPHER_AES:
+ return keylen == 16 || keylen == 24 || keylen == 32;
+ case FXCIPHER_AES2:
+ return keylen == 32;
+ case FXCIPHER_RC4:
+ return keylen >= 5 && keylen <= 16;
+ case FXCIPHER_NONE:
+ return true;
+ default:
+ NOTREACHED();
+ }
+ return false;
+}
+
} // namespace
CPDF_SecurityHandler::CPDF_SecurityHandler()
@@ -93,7 +109,11 @@ bool CPDF_SecurityHandler::OnInit(CPDF_Dictionary* pEncryptDict,
if (m_Cipher == FXCIPHER_NONE) {
return true;
}
- return CheckSecurity(password);
+ if (!CheckSecurity(password))
+ return false;
+
+ InitCryptoHandler();
+ return true;
}
bool CPDF_SecurityHandler::CheckSecurity(const ByteString& password) {
@@ -152,7 +172,7 @@ static bool LoadCryptInfo(CPDF_Dictionary* pEncryptDict,
if (keylen > 32 || keylen < 0) {
return false;
}
- return true;
+ return IsValidKeyLengthForCipher(cipher, keylen);
}
bool CPDF_SecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) {
@@ -196,14 +216,6 @@ bool CPDF_SecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict,
return true;
}
-bool CPDF_SecurityHandler::GetCryptInfo(int& cipher,
- const uint8_t*& buffer,
- int& keylen) {
- cipher = m_Cipher;
- buffer = m_EncryptKey;
- keylen = m_KeyLen;
- return true;
-}
#define FX_GET_32WORD(n, b, i) \
{ \
(n) = (uint32_t)( \
@@ -507,12 +519,12 @@ bool CPDF_SecurityHandler::IsMetadataEncrypted() const {
return m_pEncryptDict->GetBooleanFor("EncryptMetadata", true);
}
-void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const ByteString& user_password,
- const ByteString& owner_password,
- bool bDefault,
- uint32_t type) {
+void CPDF_SecurityHandler::OnCreateInternal(CPDF_Dictionary* pEncryptDict,
+ CPDF_Array* pIdArray,
+ const ByteString& user_password,
+ const ByteString& owner_password,
+ bool bDefault,
+ uint32_t type) {
int cipher = 0, key_len = 0;
if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
return;
@@ -598,19 +610,26 @@ void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
pEncryptDict->SetNewFor<CPDF_String>("U", ByteString(digest, 32), false);
}
}
+
void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
CPDF_Array* pIdArray,
const ByteString& user_password,
const ByteString& owner_password,
uint32_t type) {
- OnCreate(pEncryptDict, pIdArray, user_password, owner_password, true, type);
+ OnCreateInternal(pEncryptDict, pIdArray, user_password, owner_password, true,
+ type);
+ InitCryptoHandler();
}
+
void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
CPDF_Array* pIdArray,
const ByteString& user_password,
uint32_t type) {
- OnCreate(pEncryptDict, pIdArray, user_password, ByteString(), false, type);
+ OnCreateInternal(pEncryptDict, pIdArray, user_password, ByteString(), false,
+ type);
+ InitCryptoHandler();
}
+
void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict,
const ByteString& password,
bool bOwner,
@@ -695,7 +714,7 @@ void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict,
pEncryptDict->SetNewFor<CPDF_String>("Perms", ByteString(buf1, 16), false);
}
-bool CPDF_SecurityHandler::InitCryptoHandler() {
- m_pCryptoHandler = pdfium::MakeUnique<CPDF_CryptoHandler>();
- return m_pCryptoHandler->Init(m_pEncryptDict.Get(), this);
+void CPDF_SecurityHandler::InitCryptoHandler() {
+ m_pCryptoHandler =
+ pdfium::MakeUnique<CPDF_CryptoHandler>(m_Cipher, m_EncryptKey, m_KeyLen);
}
diff --git a/core/fpdfapi/parser/cpdf_security_handler.h b/core/fpdfapi/parser/cpdf_security_handler.h
index 753a8503a1..c92dc46862 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.h
+++ b/core/fpdfapi/parser/cpdf_security_handler.h
@@ -33,7 +33,6 @@ class CPDF_SecurityHandler {
const CPDF_Array* pIdArray,
const ByteString& password);
uint32_t GetPermissions();
- bool GetCryptInfo(int& cipher, const uint8_t*& buffer, int& keylen);
bool IsMetadataEncrypted() const;
void OnCreate(CPDF_Dictionary* pEncryptDict,
@@ -53,7 +52,6 @@ class CPDF_SecurityHandler {
uint8_t* key,
int key_len);
- bool InitCryptoHandler();
CPDF_CryptoHandler* GetCryptoHandler() const {
return m_pCryptoHandler.get();
}
@@ -84,14 +82,16 @@ class CPDF_SecurityHandler {
uint32_t permission,
bool bEncryptMetadata,
const uint8_t* key);
- void OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const ByteString& user_password,
- const ByteString& owner_password,
- bool bDefault,
- uint32_t type);
+ void OnCreateInternal(CPDF_Dictionary* pEncryptDict,
+ CPDF_Array* pIdArray,
+ const ByteString& user_password,
+ const ByteString& owner_password,
+ bool bDefault,
+ uint32_t type);
bool CheckSecurity(const ByteString& password);
+ void InitCryptoHandler();
+
int m_Version;
int m_Revision;
UnownedPtr<CPDF_Dictionary> m_pEncryptDict;