Fix bug 74157

This commit is contained in:
Svetlana Kulikova
2025-04-22 11:01:57 +03:00
parent 1c4462e2e9
commit 04d3e94dcc
4 changed files with 23 additions and 25 deletions

View File

@ -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();

View File

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

View File

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

View File

@ -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);