diff --git a/DesktopEditor/xmlsec/src/include/OOXMLSigner.h b/DesktopEditor/xmlsec/src/include/OOXMLSigner.h index dbe101363e..b468990af4 100644 --- a/DesktopEditor/xmlsec/src/include/OOXMLSigner.h +++ b/DesktopEditor/xmlsec/src/include/OOXMLSigner.h @@ -15,7 +15,7 @@ public: void SetImageValid (const std::wstring& file); void SetImageInvalid(const std::wstring& file); - int Sign(const std::wstring& sFiletoWrite); + int Sign(unsigned char*& pFiletoWrite, unsigned long& dwLenFiletoWrite); private: COOXMLSigner_private* m_internal; diff --git a/DesktopEditor/xmlsec/src/include/OOXMLVerifier.h b/DesktopEditor/xmlsec/src/include/OOXMLVerifier.h index 53087ed950..8f348fb33b 100644 --- a/DesktopEditor/xmlsec/src/include/OOXMLVerifier.h +++ b/DesktopEditor/xmlsec/src/include/OOXMLVerifier.h @@ -39,6 +39,7 @@ class Q_DECL_EXPORT COOXMLVerifier { public: COOXMLVerifier(const std::wstring& sFolder); + COOXMLVerifier(unsigned char* data, unsigned long length); ~COOXMLVerifier(); int GetSignatureCount(); diff --git a/DesktopEditor/xmlsec/src/include/ZipFolder.h b/DesktopEditor/xmlsec/src/include/ZipFolder.h index 9aa6605b0b..90cb723b15 100644 --- a/DesktopEditor/xmlsec/src/include/ZipFolder.h +++ b/DesktopEditor/xmlsec/src/include/ZipFolder.h @@ -15,7 +15,7 @@ public: virtual bool exists(const std::wstring& path) = 0; virtual void remove(const std::wstring& path) = 0; virtual void createDirectory(const std::wstring& path) = 0; - virtual void writeZipFolder (const std::wstring& path) = 0; + virtual void writeZipFolder(BYTE* data, DWORD& length) = 0; virtual std::vector getFiles(const std::wstring& path, bool bIsRecursion) = 0; }; @@ -60,7 +60,7 @@ public: if (!NSDirectory::Exists(path)) NSDirectory::CreateDirectory(path); } - virtual void writeZipFolder (const std::wstring& path) + virtual void writeZipFolder(BYTE* data, DWORD& length) { } virtual std::vector getFiles(const std::wstring& path, bool bIsRecursion) @@ -164,7 +164,7 @@ public: virtual void createDirectory(const std::wstring& path) { } - virtual void writeZipFolder (const std::wstring& path) + virtual void writeZipFolder(BYTE* data, DWORD& length) { CData* oData = new CData(); oData->SkipLen(); @@ -181,10 +181,8 @@ public: Zlib* zipFile = Zlib_Create(); BYTE* oRes = Zlib_CompressFiles(zipFile, oData->GetBuffer()); - NSFile::CFileBinary oFile; - oFile.CreateFileW(path); - oFile.WriteFile(oRes + 4, GetLength(oRes)); - oFile.CloseFile(); + data = oRes + 4; + length = GetLength(oRes); } virtual std::vector getFiles(const std::wstring& path, bool bIsRecursion) { diff --git a/DesktopEditor/xmlsec/src/src/OOXMLSigner.cpp b/DesktopEditor/xmlsec/src/src/OOXMLSigner.cpp index e8448b7f9a..489a64045d 100644 --- a/DesktopEditor/xmlsec/src/src/OOXMLSigner.cpp +++ b/DesktopEditor/xmlsec/src/src/OOXMLSigner.cpp @@ -663,7 +663,7 @@ public: return nSignNum; } - int Sign(const std::wstring& sFiletoWrite) + int Sign(BYTE*& pFiletoWrite, DWORD& dwLenFiletoWrite) { Parse(); @@ -702,7 +702,7 @@ public: NSFile::CUtf8Converter::GetUtf8StringFromUnicode(builderResult.GetData().c_str(), builderResult.GetSize(), pData, nLen); m_pZipFolder->write(m_sFolder + L"/_xmlsignatures/sig" + std::to_wstring(nSignNum + 1) + L".xml", pData, nLen); - m_pZipFolder->writeZipFolder(sFiletoWrite); + m_pZipFolder->writeZipFolder(pFiletoWrite, dwLenFiletoWrite); return (sSignedXml.empty()) ? 1 : 0; } }; @@ -737,7 +737,7 @@ void COOXMLSigner::SetImageInvalid(const std::wstring& file) m_internal->SetImageInvalid(file); } -int COOXMLSigner::Sign(const std::wstring& sFiletoWrite) +int COOXMLSigner::Sign(BYTE*& pFiletoWrite, DWORD& dwLenFiletoWrite) { - return m_internal->Sign(sFiletoWrite); + return m_internal->Sign(pFiletoWrite, dwLenFiletoWrite); } diff --git a/DesktopEditor/xmlsec/src/src/OOXMLVerifier.cpp b/DesktopEditor/xmlsec/src/src/OOXMLVerifier.cpp index e009584389..3e62e410f6 100644 --- a/DesktopEditor/xmlsec/src/src/OOXMLVerifier.cpp +++ b/DesktopEditor/xmlsec/src/src/OOXMLVerifier.cpp @@ -1,5 +1,6 @@ #include "./XmlTransform.h" #include "./../include/OOXMLVerifier.h" +#include "./../include/ZipFolder.h" class COOXMLSignature_private { @@ -12,6 +13,7 @@ public: std::string m_sImageInvalidBase64; std::wstring m_sFolder; + IZipFolder* m_pZipFolder; std::wstring m_sFile; std::string m_sDate; @@ -399,7 +401,7 @@ public: sFile = sFile.substr(0, nPos); sFile = m_sFolder + sFile; - if (!NSFile::CFileBinary::Exists(sFile)) + if (!m_pZipFolder->exists(sFile)) return OOXML_SIGNATURE_INVALID; XmlUtils::CXmlNode nodeMethod = node.ReadNode(L"DigestMethod"); @@ -420,7 +422,11 @@ public: if (!nodeTransform.IsValid()) { // simple hash - sCalcValue = m_cert->GetHash(sFile, nAlg); + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(sFile, pData, dwLen); + + sCalcValue = m_cert->GetHash(pData, dwLen, nAlg); sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue"))); MakeBase64_NOCRLF(sValue); } @@ -431,10 +437,10 @@ public: if (!oTransforms.GetValid()) return OOXML_SIGNATURE_NOTSUPPORTED; - std::string sXml; - NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sXml); - - sXml = oTransforms.Transform(sXml); + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(sFile, pData, dwLen); + std::string sXml = oTransforms.Transform(std::string((char*)pData, dwLen)); sCalcValue = m_cert->GetHash(sXml, nAlg); sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue"))); @@ -560,6 +566,7 @@ class COOXMLVerifier_private { public: std::wstring m_sFolder; + IZipFolder* m_pZipFolder; std::vector m_arSignatures; std::vector m_arSignaturesFiles; @@ -567,9 +574,10 @@ public: COOXMLVerifier_private(const std::wstring& sFolder) { m_sFolder = sFolder; + m_pZipFolder = new CZipFolder(sFolder); // check .sig file - std::vector arFiles = NSDirectory::GetFiles(m_sFolder + L"/_xmlsignatures", false); + std::vector arFiles = m_pZipFolder->getFiles(m_sFolder + L"/_xmlsignatures", false); bool bIsFound = false; for (std::vector::iterator i = arFiles.begin(); i != arFiles.end(); i++) { @@ -583,8 +591,12 @@ public: if (!bIsFound) return; + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(m_sFolder + L"/[Content_Types].xml", pData, dwLen); + XmlUtils::CXmlNode oContentTypes; - if (!oContentTypes.FromXmlFile(m_sFolder + L"/[Content_Types].xml")) + if (!oContentTypes.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen))) return; XmlUtils::CXmlNodes oOverrides = oContentTypes.GetNodes(L"Override"); @@ -599,8 +611,12 @@ public: continue; std::wstring sFile = m_sFolder + node.GetAttribute("PartName"); + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(sFile, pData, dwLen); + XmlUtils::CXmlNode nodeSig; - if (!nodeSig.FromXmlFile(sFile)) + if (!nodeSig.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen))) continue; if (nodeSig.GetName() != L"Signature") @@ -610,6 +626,69 @@ public: pSignature->m_internal->m_sFile = sFile; pSignature->m_internal->m_node = nodeSig; pSignature->m_internal->m_sFolder = m_sFolder; + pSignature->m_internal->m_pZipFolder = m_pZipFolder; + pSignature->Check(); + + m_arSignatures.push_back(pSignature); + m_arSignaturesFiles.push_back(sFile); + } + } + COOXMLVerifier_private(BYTE* data, DWORD length) + { + m_sFolder = L""; + m_pZipFolder = new CZipFolderMemory(data, length); + + // check .sig file + std::vector arFiles = m_pZipFolder->getFiles(m_sFolder + L"/_xmlsignatures", false); + bool bIsFound = false; + for (std::vector::iterator i = arFiles.begin(); i != arFiles.end(); i++) + { + if (NSFile::GetFileExtention(*i) == L"sigs") + { + bIsFound = true; + break; + } + } + + if (!bIsFound) + return; + + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(m_sFolder + L"/[Content_Types].xml", pData, dwLen); + + XmlUtils::CXmlNode oContentTypes; + if (!oContentTypes.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen))) + return; + + XmlUtils::CXmlNodes oOverrides = oContentTypes.GetNodes(L"Override"); + int nCount = oOverrides.GetCount(); + + for (int i = 0; i < nCount; i++) + { + XmlUtils::CXmlNode node; + oOverrides.GetAt(i, node); + + if (node.GetAttributeA("ContentType") != "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml") + continue; + + std::wstring sFile = m_sFolder + node.GetAttribute("PartName"); + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(sFile, pData, dwLen); + + XmlUtils::CXmlNode nodeSig; + if (!nodeSig.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen))) + continue; + + if (nodeSig.GetName() != L"Signature") + continue; + + COOXMLSignature* pSignature = new COOXMLSignature(); + pSignature->m_internal->m_sFile = sFile; + pSignature->m_internal->m_node = nodeSig; + pSignature->m_internal->m_sFolder = m_sFolder; + pSignature->m_internal->m_pZipFolder = m_pZipFolder; pSignature->Check(); m_arSignatures.push_back(pSignature); @@ -654,13 +733,17 @@ public: } if (!sFile.empty()) - NSFile::CFileBinary::Remove(sFile); + m_pZipFolder->remove(sFile); if (!bIsRemoveAll && sFile.empty()) return; + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(m_sFolder + L"/[Content_Types].xml", pData, dwLen); + XmlUtils::CXmlNode oContentTypes; - if (!oContentTypes.FromXmlFile(m_sFolder + L"/[Content_Types].xml")) + if (!oContentTypes.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen))) return; std::wstring sXml = L""; @@ -696,14 +779,24 @@ public: } } sXml += L""; - NSFile::CFileBinary::SaveToFile(m_sFolder + L"/[Content_Types].xml", sXml); + + BYTE* pXmlData = NULL; + LONG nLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sXml.c_str(), sXml.length(), pXmlData, nLen); + m_pZipFolder->write(m_sFolder + L"/[Content_Types].xml", pXmlData, nLen); if (bIsRemoveAll) { - NSDirectory::DeleteDirectory(m_sFolder + L"/_xmlsignatures"); + std::vector arrDeleteFiles = m_pZipFolder->getFiles(m_sFolder + L"/_xmlsignatures", true); + for (const std::wstring& sPath : arrDeleteFiles) + m_pZipFolder->remove(sPath); + + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(m_sFolder + L"/_rels/.rels", pData, dwLen); XmlUtils::CXmlNode oRels; - if (!oRels.FromXmlFile(m_sFolder + L"/_rels/.rels")) + if (!oRels.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen))) return; sXml = L""; @@ -725,7 +818,11 @@ public: } } sXml += L""; - NSFile::CFileBinary::SaveToFile(m_sFolder + L"/_rels/.rels", sXml); + + BYTE* pXmlData = NULL; + LONG nLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sXml.c_str(), sXml.length(), pXmlData, nLen); + m_pZipFolder->write(m_sFolder + L"/_rels/.rels", pXmlData, nLen); } else { @@ -736,8 +833,12 @@ public: std::wstring sOriginRels = m_sFolder + L"/_xmlsignatures/_rels/origin.sigs.rels"; + BYTE* pData = NULL; + DWORD dwLen = 0; + m_pZipFolder->read(sOriginRels, pData, dwLen); + XmlUtils::CXmlNode oRels; - if (!oRels.FromXmlFile(sOriginRels)) + if (!oRels.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen))) return; sXml = L""; @@ -760,7 +861,11 @@ public: } } sXml += L""; - NSFile::CFileBinary::SaveToFile(sOriginRels, sXml); + + BYTE* pXmlData = NULL; + LONG nLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sXml.c_str(), sXml.length(), pXmlData, nLen); + m_pZipFolder->write(sOriginRels, pXmlData, nLen); } } }; @@ -770,6 +875,11 @@ COOXMLVerifier::COOXMLVerifier(const std::wstring& sFolder) m_internal = new COOXMLVerifier_private(sFolder); } +COOXMLVerifier::COOXMLVerifier(BYTE* data, DWORD length) +{ + m_internal = new COOXMLVerifier_private(data, length); +} + COOXMLVerifier::~COOXMLVerifier() { RELEASEOBJECT(m_internal); @@ -789,8 +899,16 @@ COOXMLSignature* COOXMLVerifier::GetSignature(const int& index) void COOXMLVerifier::RemoveSignature(const std::string& sGuid) { + BYTE* pData = NULL; + DWORD dwLen = 0; std::wstring sFolder = m_internal->m_sFolder; + if (sFolder.empty()) + m_internal->m_pZipFolder->writeZipFolder(pData, dwLen); + m_internal->RemoveSignature(sGuid); RELEASEOBJECT(m_internal); - m_internal = new COOXMLVerifier_private(sFolder); + if (sFolder.empty()) + m_internal = new COOXMLVerifier_private(pData, dwLen); + else + m_internal = new COOXMLVerifier_private(sFolder); } diff --git a/DesktopEditor/xmlsec/src/src/XmlRels.h b/DesktopEditor/xmlsec/src/src/XmlRels.h index 7b30d9367b..8bb4cab1f1 100644 --- a/DesktopEditor/xmlsec/src/src/XmlRels.h +++ b/DesktopEditor/xmlsec/src/src/XmlRels.h @@ -161,68 +161,7 @@ public: return builder.GetData(); } - void CheckOriginSigs(const std::wstring& file) - { - int rId = 0; - std::string sReplace = ""; - std::vector::iterator i = rels.begin(); - while (i != rels.end()) - { - if (0 == i->target.find(L"_xmlsignatures/")) - { - sReplace = U_TO_UTF8(i->target); - break; - } - - std::wstring rid = i->rid; - rid = rid.substr(3); - - int nTemp = std::stoi(rid); - - if (nTemp > rId) - rId = nTemp; - - i++; - } - - if (!sReplace.empty()) - { - if (sReplace == "_xmlsignatures/origin.sigs") - return; - - std::string sXmlA; - NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA); - NSStringUtils::string_replaceA(sXmlA, sReplace, "_xmlsignatures/origin.sigs"); - - NSFile::CFileBinary::Remove(file); - NSFile::CFileBinary oFile; - oFile.CreateFileW(file); - oFile.WriteFile((BYTE*)sXmlA.c_str(), (DWORD)sXmlA.length()); - oFile.CloseFile(); - return; - } - - std::string sXmlA; - NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA); - - std::string::size_type pos = sXmlA.rfind(""); - if (pos == std::string::npos) - return; - - rId++; - std::string sRet = sXmlA.substr(0, pos); - sRet += ("\ -"); - - NSFile::CFileBinary::Remove(file); - NSFile::CFileBinary oFile; - oFile.CreateFileW(file); - oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length()); - oFile.CloseFile(); - } - - void CheckOriginSigs(BYTE* pData, LONG& nSize) + void CheckOriginSigs(BYTE*& pData, LONG& nSize) { int rId = 0; std::wstring sReplace = L"";