diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index cee3b3a48d..2ef1754de3 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -59,7 +59,7 @@ ((PdfWriter::CArrayObject*)pObj)->Add(oVal);\ } -void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::string& sKey) +void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::string& sKey, bool bMakeBinary = false) { Object oTemp; switch (obj->getType()) @@ -83,7 +83,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::str case objString: { GString* str = obj->getString(); - if (str->isBinary()) + if (str->isBinary() || bMakeBinary) { int nLength = str->getLength(); BYTE* arrId = new BYTE[nLength]; @@ -1128,7 +1128,7 @@ bool CPdfEditor::IncrementalUpdates() Object oTemp; char* chKey = encrypt.dictGetKey(nIndex); encrypt.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pEncryptDict, chKey); + DictToCDictObject(&oTemp, pEncryptDict, chKey, true); oTemp.free(); } } @@ -1139,7 +1139,7 @@ bool CPdfEditor::IncrementalUpdates() encrypt.free(); if (pTrailerDict->dictLookup("ID", &ID) && ID.isArray() && ID.arrayGet(0, &ID1) && ID1.isString()) - DictToCDictObject(&ID1, pEncryptDict, "ID"); + DictToCDictObject(&ID1, pEncryptDict, "ID", true); ID.free(); ID1.free(); xref->onEncrypted(); diff --git a/PdfFile/SrcWriter/Encrypt.cpp b/PdfFile/SrcWriter/Encrypt.cpp index f47451e399..86f71d138d 100644 --- a/PdfFile/SrcWriter/Encrypt.cpp +++ b/PdfFile/SrcWriter/Encrypt.cpp @@ -203,6 +203,7 @@ namespace PdfWriter m_unPermission = ENABLE_PRINT | ENABLE_EDIT_ALL | ENABLE_COPY | ENABLE_EDIT | PERMISSION_PAD; MemSet(m_anEncryptID, 0, ID_LEN); + m_unIDLength = ID_LEN; MemSet(m_anOwnerKey, 0, 48); MemSet(m_anUserKey, 0, 48); @@ -292,7 +293,7 @@ namespace PdfWriter } } else if (impl->m_sOwnerPassword.empty()) - return MakeFileKey2(impl->m_sUserPassword); + return MakeFileKey2((BYTE*)impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); else { int nLen = impl->m_sOwnerPassword.length(); @@ -332,9 +333,8 @@ namespace PdfWriter rc4Decryption.ProcessData(arrOwnerKey, arrOwnerKey, 32); } } - std::string sUserPassword2((char *)arrOwnerKey, 32); - return MakeFileKey2(sUserPassword2); + return MakeFileKey2(arrOwnerKey, 32); } return false; } @@ -392,28 +392,22 @@ namespace PdfWriter memcpy (pHash, K, 32); // pHash - from sha256 return true; } - bool CEncrypt::MakeFileKey2(const std::string &sUserPassword) + bool CEncrypt::MakeFileKey2(BYTE* sUserPassword, int nLength) { unsigned char sTest[32]; unsigned char sTempKey[16]; - int nLen = 0; + int nLen = nLength; bool bResult = true; - unsigned char* pBuffer = new unsigned char[72 + 16]; + unsigned char* pBuffer = new unsigned char[72 + m_unIDLength]; - if (false == sUserPassword.empty()) + if (nLen < 32) { - nLen = sUserPassword.length(); - if (nLen < 32) - { - memcpy(pBuffer, sUserPassword.c_str(), nLen); - memcpy(pBuffer + nLen, passwordPad, 32 - nLen); - } - else - memcpy(pBuffer, sUserPassword.c_str(), 32); + memcpy(pBuffer, sUserPassword, nLen); + memcpy(pBuffer + nLen, passwordPad, 32 - nLen); } else - memcpy(pBuffer, passwordPad, 32); + memcpy(pBuffer, sUserPassword, 32); memcpy(pBuffer + 32, m_anOwnerKey, 32); @@ -422,8 +416,8 @@ namespace PdfWriter pBuffer[66] = (m_unPermission >> 16) & 0xff; pBuffer[67] = (m_unPermission >> 24) & 0xff; - memcpy(pBuffer + 68, m_anEncryptID, 16); - nLen = 68 + 16; + memcpy(pBuffer + 68, m_anEncryptID, m_unIDLength); + nLen = 68 + m_unIDLength; if (!true) { pBuffer[nLen++] = 0xff; @@ -458,9 +452,9 @@ namespace PdfWriter rc4Decryption.ProcessData(sTest, sTest, 32); } memcpy(pBuffer, passwordPad, 32); - memcpy(pBuffer + 32, m_anEncryptID, 16); + memcpy(pBuffer + 32, m_anEncryptID, m_unIDLength); - MD5(pBuffer, 32 + 16, pBuffer); + MD5(pBuffer, 32 + m_unIDLength, pBuffer); bResult = (memcmp(sTest, pBuffer, 16) == 0); } diff --git a/PdfFile/SrcWriter/Encrypt.h b/PdfFile/SrcWriter/Encrypt.h index 6669257ca4..aec1dca8bc 100644 --- a/PdfFile/SrcWriter/Encrypt.h +++ b/PdfFile/SrcWriter/Encrypt.h @@ -82,7 +82,7 @@ namespace PdfWriter Impl *impl; bool MakeFileKey3(const std::string &sPassword, unsigned char *pHash, int nHashSize, unsigned char *pHash2 = NULL, int nHashSize2 = 0); - bool MakeFileKey2(const std::string &sUserPassword); + bool MakeFileKey2(BYTE* sUserPassword, int nLength); unsigned int m_unKeyLen; @@ -96,6 +96,7 @@ namespace PdfWriter unsigned int m_unRevision; //R BYTE m_anEncryptID[ID_LEN]; + unsigned int m_unIDLength; friend class CEncryptDict; friend class CDocument; diff --git a/PdfFile/SrcWriter/EncryptDictionary.cpp b/PdfFile/SrcWriter/EncryptDictionary.cpp index 5842adc7c8..8d4c731df1 100644 --- a/PdfFile/SrcWriter/EncryptDictionary.cpp +++ b/PdfFile/SrcWriter/EncryptDictionary.cpp @@ -72,6 +72,9 @@ namespace PdfWriter SET_BINARY_PARAM("UE", SetUE); SET_BINARY_PARAM("Perms", SetPerms); SET_BINARY_PARAM("ID", SetID); + pObj = Get("ID"); + if (pObj && pObj->GetType() == object_type_BINARY) + m_pEncrypt->m_unIDLength = ((CBinaryObject*)pObj)->GetLength(); Remove("ID"); SET_NUMBER_PARAM("P", SetPermission);