diff --git a/DesktopEditor/xmlsec/src/OOXMLSigner.h b/DesktopEditor/xmlsec/src/OOXMLSigner.h new file mode 100644 index 0000000000..c18b46f84a --- /dev/null +++ b/DesktopEditor/xmlsec/src/OOXMLSigner.h @@ -0,0 +1,723 @@ +#ifndef _XML_OOXMLSIGNER_H_ +#define _XML_OOXMLSIGNER_H_ + +#include "./XmlCanonicalizator.h" +#include "./XmlSignerBase.h" + +class COOXMLSigner +{ +public: + ICertificate* m_certificate; + std::wstring m_sFolder; + + std::wstring m_date; + + std::map m_content_types; + std::vector m_rels; + std::vector m_files; + + NSStringUtils::CStringBuilderA m_signed_info; + + std::wstring m_image_valid; + std::wstring m_image_invalid; + + std::wstring m_guid; + +public: + class COOXMLRelationship + { + public: + std::wstring rid; + std::wstring type; + std::wstring target; + std::wstring target_mode; + + public: + + COOXMLRelationship() + { + } + + COOXMLRelationship(XmlUtils::CXmlNode& node) + { + rid = node.GetAttribute("Id"); + type = node.GetAttribute("Type"); + target = node.GetAttribute("Target"); + + CheckTargetMode(); + } + + std::wstring GetXml() + { + NSStringUtils::CStringBuilder builder; + builder.WriteString(L""); + return builder.GetData(); + } + + static bool Compare(const COOXMLRelationship& i, const COOXMLRelationship& j) + { + return i.rid < j.rid; + } + + protected: + void CheckTargetMode() + { + if (0 == target.find(L"http") || 0 == target.find(L"www") || 0 == target.find(L"ftp")) + target_mode = L"External"; + else + target_mode = L"Internal"; + } + }; + + class COOXMLRelationships + { + public: + std::vector rels; + + public: + + COOXMLRelationships() + { + } + + COOXMLRelationships(std::wstring& file) + { + XmlUtils::CXmlNode oNode; + if (!oNode.FromXmlFile(file)) + return; + + XmlUtils::CXmlNodes oNodes; + if (!oNode.GetNodes(L"Relationship", oNodes)) + return; + + int nCount = oNodes.GetCount(); + for (int i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode oRel; + oNodes.GetAt(i, oRel); + rels.push_back(COOXMLRelationship(oRel)); + } + } + + std::wstring GetXml() + { + NSStringUtils::CStringBuilder builder; + + builder.WriteString(L""); + + // sort by rId + std::sort(rels.begin(), rels.end(), COOXMLRelationship::Compare); + + for (std::vector::iterator i = rels.begin(); i != rels.end(); i++) + builder.WriteString(i->GetXml()); + + builder.WriteString(L""); + + return builder.GetData(); + } + + std::wstring GetTransforms() + { + NSStringUtils::CStringBuilder builder; + + builder.WriteString(L""); + + for (std::vector::iterator i = rels.begin(); i != rels.end(); i++) + { + builder.WriteString(L"rid); + builder.WriteString(L"\" />"); + } + + builder.WriteString(L""); + + return builder.GetData(); + } + + void CheckOriginSigs(std::wstring& file) + { + int rId = 0; + std::vector::iterator i = rels.begin(); + while (i != rels.end()) + { + if (0 == i->target.find(L"_xmlsignatures/")) + return; + + std::wstring rid = i->rid; + rid = rid.substr(3); + + int nTemp = std::stoi(rid); + + if (nTemp > rId) + rId = nTemp; + + i++; + } + + 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(); + } + }; + +public: + COOXMLSigner(const std::wstring& sFolder, ICertificate* pContext) + { + m_sFolder = sFolder; + m_certificate = pContext; + + m_date = L"2017-04-21T08:30:21Z"; + + m_signed_info.WriteString(""); + m_signed_info.WriteString(""); + } + ~COOXMLSigner() + { + } + + std::wstring GetReference(const std::wstring& file, const std::wstring& content_type) + { + std::wstring sXml = L""; + sXml += L""; + sXml += L""; + sXml += UTF8_TO_U(m_certificate->GetHash(m_sFolder + file)); + sXml += L""; + sXml += L""; + return sXml; + } + + std::string GetHashXml(const std::wstring& xml) + { + std::string sXmlSigned = U_TO_UTF8(xml); + sXmlSigned = CXmlCanonicalizator::Execute(sXmlSigned, XML_C14N_1_0); + return m_certificate->GetHash(sXmlSigned); + } + + std::string GetReferenceMain(const std::wstring& xml, const std::wstring& id, const bool& isCannon = true) + { + std::wstring sXml1 = L""; + else + sXml1 += (L" Id=\"" + id + L"\">"); + sXml1 += xml; + sXml1 += L""; + + std::string sHash = GetHashXml(sXml1); + + std::string sRet; + if (isCannon) + sRet = ""; + + sRet += ("" + sHash + ""); + + return sRet; + } + + std::wstring GetImageBase64(const std::wstring& file) + { + BYTE* pData = NULL; + DWORD dwLen = 0; + if (!NSFile::CFileBinary::ReadAllBytes(file, &pData, dwLen)) + return L""; + + char* pDataC = NULL; + int nLen = 0; + NSFile::CBase64Converter::Encode(pData, (int)dwLen, pDataC, nLen, NSBase64::B64_BASE64_FLAG_NOCRLF); + + std::wstring sReturn = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pDataC, (LONG)nLen, FALSE); + + RELEASEARRAYOBJECTS(pData); + RELEASEARRAYOBJECTS(pDataC); + + return sReturn; + } + + std::wstring GetRelsReference(const std::wstring& file) + { + COOXMLRelationships oRels(m_sFolder + file); + + if (L"/_rels/.rels" == file) + { + oRels.CheckOriginSigs(m_sFolder + file); + + // удалим все лишнее + std::vector::iterator i = oRels.rels.begin(); + while (i != oRels.rels.end()) + { + if (0 == i->target.find(L"docProps/")) + i = oRels.rels.erase(i); + else if (0 == i->target.find(L"_xmlsignatures/")) + i = oRels.rels.erase(i); + else + i++; + } + } + + NSStringUtils::CStringBuilder builder; + builder.WriteString(L""); + builder.WriteString(oRels.GetTransforms()); + builder.WriteString(L""); + + std::wstring sXml = oRels.GetXml(); + std::string sHash = GetHashXml(sXml); + + std::wstring sHashW = UTF8_TO_U(sHash); + builder.WriteString(sHashW); + + builder.WriteString(L""); + + return builder.GetData(); + } + + int GetCountSigns(const std::wstring& file) + { + if (!NSFile::CFileBinary::Exists(file)) + { + std::wstring sRels = L"\ +\ +\ +"; + + NSFile::CFileBinary::SaveToFile(file, sRels, false); + return 1; + } + + XmlUtils::CXmlNode oNode; + oNode.FromXmlFile(file); + + XmlUtils::CXmlNodes oNodes; + oNode.GetNodes(L"Relationship", oNodes); + + int rId = oNodes.GetCount() + 1; + + std::string sXmlA; + NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA); + + std::string::size_type pos = sXmlA.rfind(""); + if (pos == std::string::npos) + return 1; + + 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(); + + return rId; + } + + void ParseContentTypes() + { + std::wstring file = m_sFolder + L"/[Content_Types].xml"; + XmlUtils::CXmlNode oNode; + oNode.FromXmlFile(file); + + XmlUtils::CXmlNodes nodesDefaults; + oNode.GetNodes(L"Default", nodesDefaults); + + XmlUtils::CXmlNodes nodesOverrides; + oNode.GetNodes(L"Override", nodesOverrides); + + int nCount = nodesDefaults.GetCount(); + for (int i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode node; + nodesDefaults.GetAt(i, node); + + m_content_types.insert(std::pair(node.GetAttribute("Extension"), node.GetAttribute("ContentType"))); + } + + nCount = nodesOverrides.GetCount(); + for (int i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode node; + nodesOverrides.GetAt(i, node); + + m_content_types.insert(std::pair(node.GetAttribute("PartName"), node.GetAttribute("ContentType"))); + } + } + + void Parse() + { + // 1) Parse Content_Types.xml + ParseContentTypes(); + + // 2) Parse files in directory + std::vector files = NSDirectory::GetFiles(m_sFolder, true); + + // 3) Check each file + std::wstring sFolder = m_sFolder; + NSStringUtils::string_replace(sFolder, L"\\", L"/"); + for (std::vector::iterator i = files.begin(); i != files.end(); i++) + { + std::wstring sCheckFile = *i; + NSStringUtils::string_replace(sCheckFile, L"\\", L"/"); + + if (0 != sCheckFile.find(sFolder)) + continue; + + // make cool filename + sCheckFile = sCheckFile.substr(sFolder.length()); + + // check needed file + if (0 == sCheckFile.find(L"/_xmlsignatures") || + 0 == sCheckFile.find(L"/docProps") || + 0 == sCheckFile.find(L"/[Content_Types].xml")) + continue; + + // check rels and add to needed array + std::wstring::size_type posExt = sCheckFile.rfind(L"."); + if (std::wstring::npos == posExt) + continue; + + std::wstring sExt = sCheckFile.substr(posExt + 1); + if (sExt == L"rels") + m_rels.push_back(sCheckFile); + else + m_files.push_back(sCheckFile); + } + + std::sort(m_rels.begin(), m_rels.end()); + std::sort(m_files.begin(), m_files.end()); + } + + void WriteRelsReferences(NSStringUtils::CStringBuilder& builder) + { + for (std::vector::iterator i = m_rels.begin(); i != m_rels.end(); i++) + { + builder.WriteString(GetRelsReference(*i)); + } + } + + void WriteFilesReferences(NSStringUtils::CStringBuilder& builder) + { + for (std::vector::iterator i = m_files.begin(); i != m_files.end(); i++) + { + std::wstring sFile = *i; + std::wstring sContentType = L"application/xml"; + + std::map::iterator _find = m_content_types.find(sFile); + if (_find != m_content_types.end()) + { + sContentType = _find->second; + } + else + { + std::wstring::size_type posExt = sFile.rfind(L"."); + if (std::wstring::npos != posExt) + { + std::wstring sExt = sFile.substr(posExt + 1); + + _find = m_content_types.find(sExt); + if (_find != m_content_types.end()) + sContentType = _find->second; + } + } + + builder.WriteString(GetReference(sFile, sContentType)); + } + } + + void WriteManifest(NSStringUtils::CStringBuilder& builder) + { + builder.WriteString(L""); + WriteRelsReferences(builder); + WriteFilesReferences(builder); + builder.WriteString(L""); + } + + void CorrectContentTypes(int nCountSigsNeeds) + { + std::wstring file = m_sFolder + L"/[Content_Types].xml"; + XmlUtils::CXmlNode oNode; + oNode.FromXmlFile(file); + + XmlUtils::CXmlNodes nodesDefaults; + oNode.GetNodes(L"Default", nodesDefaults); + + XmlUtils::CXmlNodes nodesOverrides; + oNode.GetNodes(L"Override", nodesOverrides); + + std::string sAddition = ""; + + bool bIsSigsExist = false; + int nCount = nodesDefaults.GetCount(); + for (int i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode node; + nodesDefaults.GetAt(i, node); + + if ("sigs" == node.GetAttributeA("Extension") && + "application/vnd.openxmlformats-package.digital-signature-origin" == node.GetAttributeA("ContentType")) + { + bIsSigsExist = true; + break; + } + } + + if (!bIsSigsExist) + sAddition += ""; + + int nCountSigs = 0; + nCount = nodesOverrides.GetCount(); + for (int i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode node; + nodesOverrides.GetAt(i, node); + + if ("application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml" == node.GetAttributeA("ContentType")) + { + ++nCountSigs; + } + } + + for (int i = nCountSigs; i < nCountSigsNeeds; ++i) + { + sAddition += ""; + } + + std::string sXmlA; + NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA); + + std::string::size_type pos = sXmlA.rfind(""); + if (pos == std::string::npos) + return; + + std::string sRet = sXmlA.substr(0, pos); + sRet += sAddition; + sRet += ""; + + NSFile::CFileBinary::Remove(file); + + NSFile::CFileBinary oFile; + oFile.CreateFileW(file); + oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length()); + oFile.CloseFile(); + } + + void SetGuid(const std::wstring& guid) + { + m_guid = guid; + } + void SetImageValid(const std::wstring& file) + { + m_image_valid = GetImageBase64(file); + } + void SetImageInvalid(const std::wstring& file) + { + m_image_invalid = GetImageBase64(file); + } + + std::wstring GeneratePackageObject() + { + NSStringUtils::CStringBuilder builder; + WriteManifest(builder); + + builder.WriteString(L""); + builder.WriteString(L""); + builder.WriteString(L"YYYY-MM-DDThh:mm:ssTZD"); + builder.WriteString(L""); + builder.WriteString(m_date); + builder.WriteString(L""); + builder.WriteString(L""); + + std::wstring sXml = builder.GetData(); + + m_signed_info.WriteString(""); + m_signed_info.WriteString(GetReferenceMain(sXml, L"idPackageObject", false)); + m_signed_info.WriteString(""); + + return (L"" + sXml + L""); + } + std::wstring GenerateOfficeObject() + { + NSStringUtils::CStringBuilder builder; + + builder.WriteString(L""); + builder.WriteString(L""); + builder.WriteString(L""); + builder.WriteString(m_guid); + builder.WriteString(L""); + builder.WriteString(L""); + builder.WriteString(L""); + builder.WriteString(m_image_valid); + builder.WriteString(L""); + builder.WriteString(L"\ +10.0\ +16.0\ +16.0\ +2\ +1680\ +1050\ +32\ +{00000000-0000-0000-0000-000000000000}\ +\ +9\ +2\ +\ +\ +"); + + m_signed_info.WriteString(""); + m_signed_info.WriteString(GetReferenceMain(builder.GetData(), L"idOfficeObject", false)); + m_signed_info.WriteString(""); + + return (L"" + builder.GetData() + L""); + } + + std::wstring GenerateImageObject() + { + if (m_image_valid.empty()) + return L""; + + m_signed_info.WriteString(""); + m_signed_info.WriteString(GetReferenceMain(m_image_valid, L"idValidSigLnImg", false)); + m_signed_info.WriteString(""); + + m_signed_info.WriteString(""); + m_signed_info.WriteString(GetReferenceMain(m_image_invalid, L"idInvalidSigLnImg", false)); + m_signed_info.WriteString(""); + + return (L"" + m_image_valid + L"" + m_image_invalid + L""); + } + + std::wstring GenerateSignPropertiesObject() + { + std::wstring sName = m_certificate->GetSignerName(); + + std::string sKeyA = m_certificate->GetNumber(); + std::wstring sKey = UTF8_TO_U(sKeyA); + + std::wstring sXml = (L"\ +" + m_date + L"\ +\ +\ +\ +\ +MJJT2Y0iMxaPGVXBmOLb9bY60pA=\ +\ +\ +CN=" + sName + L"\ +" + sKey + L"\ +\ +\ +\ +\ +\ +\ +"); + + std::wstring sSignedXml = L""; + sSignedXml += sXml; + sSignedXml += L""; + + std::string sXmlTmp = CXmlCanonicalizator::Execute(U_TO_UTF8(sSignedXml), XML_C14N_1_0); + + m_signed_info.WriteString(""); + m_signed_info.WriteString(""); + m_signed_info.WriteString(""); + m_signed_info.WriteString(m_certificate->GetHash(sXmlTmp)); + m_signed_info.WriteString(""); + + return (L"\ +" + sXml + L""); + } + + int AddSignatureReference() + { + std::wstring sDirectory = m_sFolder + L"/_xmlsignatures"; + + if (!NSDirectory::Exists(sDirectory)) + NSDirectory::CreateDirectory(sDirectory); + + if (!NSFile::CFileBinary::Exists(sDirectory + L"/origin.sigs")) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(sDirectory + L"/origin.sigs"); + oFile.CloseFile(); + } + + if (!NSDirectory::Exists(sDirectory + L"/_rels")) + NSDirectory::CreateDirectory(sDirectory + L"/_rels"); + + int nSignNum = GetCountSigns(sDirectory + L"/_rels/origin.sigs.rels"); + + CorrectContentTypes(nSignNum); + + return nSignNum; + } + + void Sign() + { + Parse(); + + std::string sSignedData; + + NSStringUtils::CStringBuilder builderMain; + + builderMain.WriteString(GeneratePackageObject()); + builderMain.WriteString(GenerateOfficeObject()); + builderMain.WriteString(GenerateSignPropertiesObject()); + builderMain.WriteString(GenerateImageObject()); + + std::string sSignedInfoData = m_signed_info.GetData(); + std::string sSignedXml = "" + sSignedInfoData + ""; + sSignedXml = CXmlCanonicalizator::Execute(sSignedXml, XML_C14N_1_0); + sSignedXml = m_certificate->Sign(sSignedXml); + + NSStringUtils::CStringBuilder builderResult; + builderResult.WriteString(L""); + builderResult.WriteString(UTF8_TO_U(sSignedInfoData)); + builderResult.WriteString(L""); + builderResult.WriteString(L""); + builderResult.WriteString(UTF8_TO_U(sSignedXml)); + builderResult.WriteString(L""); + builderResult.WriteString(L""); + builderResult.WriteString(UTF8_TO_U(m_certificate->GetCertificateBase64())); + builderResult.WriteString(L""); + + builderResult.Write(builderMain); + builderResult.WriteString(L""); + + int nSignNum = AddSignatureReference(); + + NSFile::CFileBinary::SaveToFile(m_sFolder + L"/_xmlsignatures/sig" + std::to_wstring(nSignNum) + L".xml", builderResult.GetData(), false); + } +}; + +#endif //_XML_OOXMLSIGNER_H_ diff --git a/DesktopEditor/xmlsec/src/XmlCanonicalizator.h b/DesktopEditor/xmlsec/src/XmlCanonicalizator.h new file mode 100644 index 0000000000..52775b08ef --- /dev/null +++ b/DesktopEditor/xmlsec/src/XmlCanonicalizator.h @@ -0,0 +1,84 @@ +#ifndef _XML_CANONICALIZATOR_H_ +#define _XML_CANONICALIZATOR_H_ + +#include "../../common/File.h" +#include "../../common/Directory.h" + +#include "../../common/StringBuilder.h" +#include "../../xml/include/xmlutils.h" +#include "../../xml/libxml2/include/libxml/c14n.h" + +class CXmlCanonicalizator +{ +private: + class CXmlBuffer + { + public: + NSStringUtils::CStringBuilderA builder; + + public: + CXmlBuffer() + { + } + ~CXmlBuffer() + { + } + }; + + static int buffer_xmlBufferIOWrite(CXmlBuffer* buf, const char* buffer, int len) + { + buf->builder.WriteString(buffer, (size_t)len); + return len; + } + + static int buffer_xmlBufferIOClose(CXmlBuffer* buf) + { + return 0; + } + + static int buffer_xmlC14NIsVisibleCallback(void * user_data, xmlNodePtr node, xmlNodePtr parent) + { + if (node->type == XML_TEXT_NODE) + { + const char* cur = (char*)node->content; + size_t size = strlen(cur); + for (size_t i = 0; i < size; ++i, ++cur) + { + if (*cur != '\n' && *cur != '\r' && *cur != '\t') + return 1; + } + return 0; + } + return 1; + } + +public: + static std::string Execute(const std::string& sXml, int mode) + { + xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length()); + + CXmlBuffer bufferC14N; + xmlOutputBufferPtr _buffer = xmlOutputBufferCreateIO((xmlOutputWriteCallback)buffer_xmlBufferIOWrite, + (xmlOutputCloseCallback)buffer_xmlBufferIOClose, + &bufferC14N, + NULL); + + xmlC14NExecute(xmlDoc, buffer_xmlC14NIsVisibleCallback, NULL, mode, NULL, 0, _buffer); + + xmlOutputBufferClose(_buffer); + + return bufferC14N.builder.GetData(); + } + + static std::string Execute(const std::wstring& sXmlFile, int mode) + { + std::string sXml; + NSFile::CFileBinary::ReadAllTextUtf8A(sXmlFile, sXml); + + xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length()); + + return Execute(sXml, mode); + } +}; + +#endif //_XML_CANONICALIZATOR_H_ diff --git a/DesktopEditor/xmlsec/src/XmlSignerBase.h b/DesktopEditor/xmlsec/src/XmlSignerBase.h new file mode 100644 index 0000000000..f0d91d7d4c --- /dev/null +++ b/DesktopEditor/xmlsec/src/XmlSignerBase.h @@ -0,0 +1,40 @@ +#ifndef _XMLSIGNER_BASE_H_ +#define _XMLSIGNER_BASE_H_ + +#include "../../common/File.h" +#include "../../common/BigInteger.h" + +#include +#include +#include + +class ICertificate +{ +public: + ICertificate() + { + } + + virtual ~ICertificate() + { + } + +public: + virtual std::string GetNumber() = 0; + virtual std::wstring GetSignerName() = 0; + + virtual std::string GetCertificateBase64() = 0; + virtual std::string GetCertificateHash() = 0; + +public: + virtual std::string Sign(std::string sXml) = 0; + virtual std::string GetHash(unsigned char* pData, unsigned int nSize) = 0; + virtual std::string GetHash(std::string& sXml) = 0; + virtual std::string GetHash(std::wstring& sXmlFile) = 0; + virtual bool Verify(std::string& sXml, std::string& sXmlSignature) = 0; + +public: + virtual bool ShowSelectDialog() = 0; +}; + +#endif // _XMLSIGNER_BASE_H_ diff --git a/DesktopEditor/xmlsec/src/XmlSigner_mscrypto.h b/DesktopEditor/xmlsec/src/XmlSigner_mscrypto.h new file mode 100644 index 0000000000..b26d9280a1 --- /dev/null +++ b/DesktopEditor/xmlsec/src/XmlSigner_mscrypto.h @@ -0,0 +1,314 @@ +#ifndef _XMLSIGNER_MSCRYPTO_H_ +#define _XMLSIGNER_MSCRYPTO_H_ + +#include "./XmlSignerBase.h" + +#include +#include +#include +#include + +class CCertificate_mscrypto : public ICertificate +{ +public: + HCERTSTORE m_store; + PCCERT_CONTEXT m_context; + +public: + CCertificate_mscrypto() : ICertificate() + { + m_store = NULL; + m_context = NULL; + } + CCertificate_mscrypto(PCCERT_CONTEXT ctx) : ICertificate() + { + m_store = NULL; + m_context = ctx; + } + + virtual ~CCertificate_mscrypto() + { + if (m_store != NULL) + { + if (NULL != m_context) + CertFreeCertificateContext(m_context); + + CertCloseStore(m_store, 0); + } + } + +public: + virtual std::string GetNumber() + { + if (!m_context) + return ""; + + int nNumberLen = (int)m_context->pCertInfo->SerialNumber.cbData; + BYTE* pNumberData = new BYTE[nNumberLen]; + ConvertEndian(m_context->pCertInfo->SerialNumber.pbData, pNumberData, (DWORD)nNumberLen); + CBigInteger oInteger(pNumberData, nNumberLen); + delete[] pNumberData; + + return oInteger.ToString(); + } + + virtual std::wstring GetSignerName() + { + if (!m_context) + return L""; + + DWORD dwNameLen = CertGetNameStringW(m_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0); + wchar_t* pNameData = new wchar_t[dwNameLen]; + CertGetNameStringW(m_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, pNameData, dwNameLen); + std::wstring sName(pNameData); + RELEASEARRAYOBJECTS(pNameData); + return sName; + } + + virtual std::string GetCertificateBase64() + { + if (!m_context) + return ""; + + char* pData = NULL; + int nDataLen = 0; + NSFile::CBase64Converter::Encode(m_context->pbCertEncoded, (int)m_context->cbCertEncoded, pData, nDataLen, NSBase64::B64_BASE64_FLAG_NOCRLF); + std::string sReturn(pData, nDataLen); + RELEASEARRAYOBJECTS(pData); + return sReturn; + } + + virtual std::string GetCertificateHash() + { + return GetHash(m_context->pbCertEncoded, (unsigned int)m_context->cbCertEncoded); + } + +public: + virtual std::string Sign(std::string sXml) + { + BOOL bResult = TRUE; + DWORD dwKeySpec = 0; + HCRYPTHASH hHash = NULL; + + HCRYPTPROV hCryptProv = NULL; + bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL); + + if (!bResult) + return ""; + + bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); + if (!bResult) + { + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0); + if (!bResult) + { + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + DWORD dwSigLen = 0; + BYTE* pbSignature = NULL; + bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSigLen); + + if (!bResult) + { + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + pbSignature = new BYTE[dwSigLen]; + bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, &dwSigLen); + + if (!bResult) + { + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + BYTE* pbSignatureMem = new BYTE[dwSigLen]; + ConvertEndian(pbSignature, pbSignatureMem, dwSigLen); + + char* pBase64 = NULL; + int nBase64Len = 0; + NSFile::CBase64Converter::Encode(pbSignatureMem, (int)dwSigLen, pBase64, nBase64Len, NSBase64::B64_BASE64_FLAG_NONE); + + delete[] pbSignature; + delete[] pbSignatureMem; + + bResult = CryptDestroyHash(hHash); + + std::string sReturn(pBase64, nBase64Len); + + delete[] pBase64; + + CryptReleaseContext(hCryptProv, 0); + + return sReturn; + } + + virtual std::string GetHash(unsigned char* pData, unsigned int nSize) + { + BOOL bResult = TRUE; + DWORD dwKeySpec = 0; + HCRYPTHASH hHash = NULL; + + DWORD dwSize = (DWORD)nSize; + + HCRYPTPROV hCryptProv = NULL; + + bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL); + + if (!bResult) + return ""; + + bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); + if (!bResult) + { + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + bResult = CryptHashData(hHash, pData, dwSize, 0); + if (!bResult) + { + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + DWORD cbHashSize = 0, dwCount = sizeof(DWORD); + bResult = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHashSize, &dwCount, 0); + + if (!bResult) + { + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + BYTE* pDataHashRaw = new BYTE[dwCount]; + + bResult = CryptGetHashParam(hHash, HP_HASHVAL, pDataHashRaw, &cbHashSize, 0); + + if (!bResult) + { + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + return ""; + } + + char* pBase64_hash = NULL; + int nBase64Len_hash = 0; + NSFile::CBase64Converter::Encode(pDataHashRaw, (int)cbHashSize, pBase64_hash, nBase64Len_hash, NSBase64::B64_BASE64_FLAG_NOCRLF); + + std::string sReturn(pBase64_hash, nBase64Len_hash); + delete [] pBase64_hash; + + //delete [] pDataHashRaw; + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + + return sReturn; + } + + virtual std::string GetHash(std::string& sXml) + { + return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length()); + } + + virtual std::string GetHash(std::wstring& sXmlFile) + { + BYTE* pFileData = NULL; + DWORD dwFileDataLen = 0; + NSFile::CFileBinary::ReadAllBytes(sXmlFile, &pFileData, dwFileDataLen); + + if (0 == dwFileDataLen) + return ""; + + std::string sReturn = GetHash(pFileData, dwFileDataLen); + + RELEASEARRAYOBJECTS(pFileData); + return sReturn; + } + + virtual bool Verify(std::string& sXml, std::string& sXmlSignature) + { + DWORD dwKeySpec = 0; + HCRYPTHASH hHash = NULL; + HCRYPTKEY hPubKey = NULL; + + HCRYPTPROV hCryptProv = NULL; + BOOL bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL); + + if (!bResult) + return FALSE; + + bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); + + if (!bResult) + { + CryptReleaseContext(hCryptProv, 0); + return FALSE; + } + + BYTE* pDataHash = NULL; + DWORD dwHashLen = 0; + int nTmp = 0; + NSFile::CBase64Converter::Decode((char*)sXmlSignature.c_str(), (int)sXmlSignature.length(), pDataHash, nTmp); + dwHashLen = (DWORD)nTmp; + + BYTE* pDataHashMem = new BYTE[dwHashLen]; + ConvertEndian(pDataHash, pDataHashMem, dwHashLen); + + RELEASEARRAYOBJECTS(pDataHash); + + bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0); + + // Get the public key from the certificate + CryptImportPublicKeyInfo(hCryptProv, m_context->dwCertEncodingType, &m_context->pCertInfo->SubjectPublicKeyInfo, &hPubKey); + + BOOL bResultRet = CryptVerifySignature(hHash, pDataHashMem, dwHashLen, hPubKey, NULL, 0); + + delete[] pDataHashMem; + + bResult = CryptDestroyHash(hHash); + + CryptDestroyKey(hPubKey); + CryptReleaseContext(hCryptProv, 0); + + return bResultRet && bResult; + } + +public: + virtual bool ShowSelectDialog() + { + m_store = CertOpenSystemStoreA(NULL, "MY"); + if (!m_store) + return false; + + m_context = CryptUIDlgSelectCertificateFromStore(m_store, NULL, NULL, NULL, CRYPTUI_SELECT_LOCATION_COLUMN, 0, NULL); + if (!m_context) + { + CertCloseStore(m_store, 0); + m_store = NULL; + return false; + } + return true; + } + +private: + void ConvertEndian(const BYTE* src, BYTE* dst, DWORD size) + { + for(BYTE* p = dst + size - 1; p >= dst; ++src, --p) + (*p) = (*src); + } +}; + +#endif // _XMLSIGNER_MSCRYPTO_H_ diff --git a/DesktopEditor/xmlsec/test/windows_list_serts/main.cpp b/DesktopEditor/xmlsec/test/windows_list_serts/main.cpp index c06f28a924..af3a8d0774 100644 --- a/DesktopEditor/xmlsec/test/windows_list_serts/main.cpp +++ b/DesktopEditor/xmlsec/test/windows_list_serts/main.cpp @@ -1,1449 +1,28 @@ -#include -#include -#include -#include - -#include -#include - -#include "../../../common/File.h" -#include "../../../common/Directory.h" -#include "../../../common/BigInteger.h" - -#include "../../../xml/include/xmlutils.h" -#include "../../../xml/libxml2/include/libxml/c14n.h" - -#include +#include "../../src/XmlCanonicalizator.h" +#include "../../src/XmlSigner_mscrypto.h" +#include "../../src/OOXMLSigner.h" #pragma comment (lib, "crypt32.lib") #pragma comment (lib, "cryptui.lib") #pragma comment (lib, "Advapi32.lib") -class CXmlCanonicalizator -{ -private: - class CXmlBuffer - { - public: - NSStringUtils::CStringBuilderA builder; - - public: - CXmlBuffer() - { - } - ~CXmlBuffer() - { - } - }; - - static int buffer_xmlBufferIOWrite(CXmlBuffer* buf, const char* buffer, int len) - { - buf->builder.WriteString(buffer, (size_t)len); - return len; - } - - static int buffer_xmlBufferIOClose(CXmlBuffer* buf) - { - return 0; - } - - static int buffer_xmlC14NIsVisibleCallback(void * user_data, xmlNodePtr node, xmlNodePtr parent) - { - if (node->type == XML_TEXT_NODE) - { - const char* cur = (char*)node->content; - size_t size = strlen(cur); - for (size_t i = 0; i < size; ++i, ++cur) - { - if (*cur != '\n' && *cur != '\r' && *cur != '\t') - return 1; - } - return 0; - } - return 1; - } - -public: - static std::string Execute(const std::string& sXml, int mode) - { - xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length()); - - CXmlBuffer bufferC14N; - xmlOutputBufferPtr _buffer = xmlOutputBufferCreateIO((xmlOutputWriteCallback)buffer_xmlBufferIOWrite, - (xmlOutputCloseCallback)buffer_xmlBufferIOClose, - &bufferC14N, - NULL); - - xmlC14NExecute(xmlDoc, buffer_xmlC14NIsVisibleCallback, NULL, mode, NULL, 0, _buffer); - - xmlOutputBufferClose(_buffer); - - return bufferC14N.builder.GetData(); - } - - static std::string Execute(const std::wstring& sXmlFile, int mode) - { - std::string sXml; - NSFile::CFileBinary::ReadAllTextUtf8A(sXmlFile, sXml); - - xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length()); - - return Execute(sXml, mode); - } -}; - -class CXmlSigner -{ -private: - PCCERT_CONTEXT m_context; - -public: - CXmlSigner(PCCERT_CONTEXT pCertContext) - { - m_context = pCertContext; - } - ~CXmlSigner() - { - } - -public: - - std::string Sign(std::string sXml) - { - BOOL bResult = TRUE; - DWORD dwKeySpec = 0; - HCRYPTHASH hHash = NULL; - - HCRYPTPROV hCryptProv = NULL; - bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL); - - if (!bResult) - return ""; - - bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); - if (!bResult) - { - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0); - if (!bResult) - { - CryptDestroyHash(hHash); - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - DWORD dwSigLen = 0; - BYTE* pbSignature = NULL; - bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSigLen); - - if (!bResult) - { - CryptDestroyHash(hHash); - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - pbSignature = new BYTE[dwSigLen]; - bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, &dwSigLen); - - if (!bResult) - { - CryptDestroyHash(hHash); - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - BYTE* pbSignatureMem = new BYTE[dwSigLen]; - ConvertEndian(pbSignature, pbSignatureMem, dwSigLen); - - char* pBase64 = NULL; - int nBase64Len = 0; - NSFile::CBase64Converter::Encode(pbSignatureMem, (int)dwSigLen, pBase64, nBase64Len, NSBase64::B64_BASE64_FLAG_NONE); - - delete[] pbSignature; - delete[] pbSignatureMem; - - bResult = CryptDestroyHash(hHash); - - std::string sReturn(pBase64, nBase64Len); - - delete[] pBase64; - - CryptReleaseContext(hCryptProv, 0); - - return sReturn; - } - - std::string GetHash(BYTE* pData, DWORD dwSize) - { - BOOL bResult = TRUE; - DWORD dwKeySpec = 0; - HCRYPTHASH hHash = NULL; - - HCRYPTPROV hCryptProv = NULL; - - bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL); - - if (!bResult) - return ""; - - bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); - if (!bResult) - { - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - bResult = CryptHashData(hHash, pData, dwSize, 0); - if (!bResult) - { - CryptDestroyHash(hHash); - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - DWORD cbHashSize = 0, dwCount = sizeof(DWORD); - bResult = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHashSize, &dwCount, 0); - - if (!bResult) - { - CryptDestroyHash(hHash); - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - BYTE* pDataHashRaw = new BYTE[dwCount]; - - bResult = CryptGetHashParam(hHash, HP_HASHVAL, pDataHashRaw, &cbHashSize, 0); - - if (!bResult) - { - CryptDestroyHash(hHash); - CryptReleaseContext(hCryptProv, 0); - return ""; - } - - char* pBase64_hash = NULL; - int nBase64Len_hash = 0; - NSFile::CBase64Converter::Encode(pDataHashRaw, (int)cbHashSize, pBase64_hash, nBase64Len_hash, NSBase64::B64_BASE64_FLAG_NOCRLF); - - std::string sReturn(pBase64_hash, nBase64Len_hash); - delete [] pBase64_hash; - - //delete [] pDataHashRaw; - CryptDestroyHash(hHash); - CryptReleaseContext(hCryptProv, 0); - - return sReturn; - } - - std::string GetHash(std::string& sXml) - { - return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length()); - } - - std::string GetHash(std::wstring& sXmlFile) - { - BYTE* pFileData = NULL; - DWORD dwFileDataLen = 0; - NSFile::CFileBinary::ReadAllBytes(sXmlFile, &pFileData, dwFileDataLen); - - if (0 == dwFileDataLen) - return ""; - - std::string sReturn = GetHash(pFileData, dwFileDataLen); - - RELEASEARRAYOBJECTS(pFileData); - return sReturn; - } - - BOOL Verify(std::string& sXml, std::string& sXmlSignature) - { - DWORD dwKeySpec = 0; - HCRYPTHASH hHash = NULL; - HCRYPTKEY hPubKey = NULL; - - HCRYPTPROV hCryptProv = NULL; - BOOL bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL); - - if (!bResult) - return FALSE; - - bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); - - if (!bResult) - { - CryptReleaseContext(hCryptProv, 0); - return FALSE; - } - - BYTE* pDataHash = NULL; - DWORD dwHashLen = 0; - int nTmp = 0; - NSFile::CBase64Converter::Decode((char*)sXmlSignature.c_str(), (int)sXmlSignature.length(), pDataHash, nTmp); - dwHashLen = (DWORD)nTmp; - - BYTE* pDataHashMem = new BYTE[dwHashLen]; - ConvertEndian(pDataHash, pDataHashMem, dwHashLen); - - RELEASEARRAYOBJECTS(pDataHash); - - bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0); - - // Get the public key from the certificate - CryptImportPublicKeyInfo(hCryptProv, m_context->dwCertEncodingType, &m_context->pCertInfo->SubjectPublicKeyInfo, &hPubKey); - - BOOL bResultRet = CryptVerifySignature(hHash, pDataHashMem, dwHashLen, hPubKey, NULL, 0); - - delete[] pDataHashMem; - - bResult = CryptDestroyHash(hHash); - - CryptDestroyKey(hPubKey); - CryptReleaseContext(hCryptProv, 0); - - return bResultRet && bResult; - } - - std::string GetCertificateBase64() - { - char* pData = NULL; - int nDataLen = 0; - NSFile::CBase64Converter::Encode(m_context->pbCertEncoded, (int)m_context->cbCertEncoded, pData, nDataLen, NSBase64::B64_BASE64_FLAG_NOCRLF); - std::string sReturn(pData, nDataLen); - RELEASEARRAYOBJECTS(pData); - return sReturn; - } - - std::string GetCertificateHash() - { - return GetHash(m_context->pbCertEncoded, (int)m_context->cbCertEncoded); - } - -public: - static void ConvertEndian(const BYTE* src, BYTE* dst, DWORD size) - { - for(BYTE* p = dst + size - 1; p >= dst; ++src, --p) - (*p) = (*src); - } -}; - -#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) -void MyHandleError(char *s); - -bool Sign(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile); -bool Verify(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile); -bool SignDocument(std::wstring sFolderOOXML, PCCERT_CONTEXT pCertContext, std::wstring sign_id); - void main(void) { - if (false) - { - CBigInteger int1("345097"); - CBigInteger int2("87960324"); + //std::wstring sFolderOOOXML = NSFile::GetProcessDirectory() + L"/ImageStamp"; + //std::wstring sSignId = L"{39B6B9C7-60AD-45A2-9F61-40C74A24042E}"; - CBigInteger val1 = int1 + int2; - CBigInteger val2 = int1 - int2; - CBigInteger val3 = int1 * int2; + std::wstring sFolderOOXML = L"D:\\555"; + std::wstring sSignId = L"{9792D33F-AB37-4E5B-A465-481B9465818B}"; - CBigInteger int3("66A1F302407647974D18D489855371B5", 16); + CCertificate_mscrypto oCertificate; + if (!oCertificate.ShowSelectDialog()) + return; - unsigned char buffer[16] = { 0x66, 0xA1, 0xF3, 0x02, 0x40, 0x76, 0x47, 0x97, 0x4D, 0x18, 0xD4, 0x89, 0x85, 0x53, 0x71, 0xB5 }; - CBigInteger val4(buffer, 16); + COOXMLSigner oOOXMLSigner(sFolderOOXML, &oCertificate); - std::string sValue = int3.ToString(); - } - - //------------------------------------------------------------------- - // Copyright (C) Microsoft. All rights reserved. - // This program lists all of the certificates in a system certificate - // store and all of the property identifier numbers of those - // certificates. It also demonstrates the use of two - // UI functions. One, CryptUIDlgSelectCertificateFromStore, - // displays the certificates in a store - // and allows the user to select one of them, - // The other, CryptUIDlgViewContext, - // displays the contents of a single certificate. - - //------------------------------------------------------------------- - // Declare and initialize variables. - - HCERTSTORE hCertStore; - PCCERT_CONTEXT pCertContext=NULL; - char pszNameString[256]; - char pszStoreName[256]; - void* pvData; - DWORD cbData; - DWORD dwPropId = 0; - // Zero must be used on the first - // call to the function. After that, - // the last returned property identifier is passed. - - //------------------------------------------------------------------- - // Begin processing and Get the name of the system certificate store - // to be enumerated. Output here is to stderr so that the program - // can be run from the command line and stdout can be redirected - // to a file. - /* - fprintf(stderr,"Please enter the store name:"); - gets_s(pszStoreName, sizeof(pszStoreName)); - fprintf(stderr,"The store name is %s.\n",pszStoreName); - */ - pszStoreName[0] = 'M'; - pszStoreName[1] = 'Y'; - pszStoreName[2] = '\0'; - - //------------------------------------------------------------------- - // Open a system certificate store. - - if ( hCertStore = CertOpenSystemStore(NULL, pszStoreName)) - { - fprintf(stderr,"The %s store has been opened. \n", pszStoreName); - } - else - { - // If the store was not opened, exit to an error routine. - MyHandleError("The store was not opened."); - } - - //------------------------------------------------------------------- - // Use CertEnumCertificatesInStore to get the certificates - // from the open store. pCertContext must be reset to - // NULL to retrieve the first certificate in the store. - - // pCertContext = NULL; - -#ifdef ENUMS_CERTS - while(pCertContext= CertEnumCertificatesInStore( - hCertStore, - pCertContext)) - { - //------------------------------------------------------------------- - // A certificate was retrieved. Continue. - //------------------------------------------------------------------- - // Display the certificate. - - if ( CryptUIDlgViewContext( - CERT_STORE_CERTIFICATE_CONTEXT, - pCertContext, - NULL, - NULL, - 0, - NULL)) - { - // printf("OK\n"); - } - else - { - MyHandleError("UI failed."); - } - - if(CertGetNameString( - pCertContext, - CERT_NAME_SIMPLE_DISPLAY_TYPE, - 0, - NULL, - pszNameString, - 128)) - { - printf("\nCertificate for %s \n",pszNameString); - } - else - fprintf(stderr,"CertGetName failed. \n"); - - //------------------------------------------------------------------- - // Loop to find all of the property identifiers for the specified - // certificate. The loop continues until - // CertEnumCertificateContextProperties returns zero. - - while(dwPropId = CertEnumCertificateContextProperties( - pCertContext, // The context whose properties are to be listed. - dwPropId)) // Number of the last property found. - // This must be zero to find the first - // property identifier. - { - //------------------------------------------------------------------- - // When the loop is executed, a property identifier has been found. - // Print the property number. - - printf("Property # %d found->", dwPropId); - - //------------------------------------------------------------------- - // Indicate the kind of property found. - - switch(dwPropId) - { - case CERT_FRIENDLY_NAME_PROP_ID: - { - printf("Display name: "); - break; - } - case CERT_SIGNATURE_HASH_PROP_ID: - { - printf("Signature hash identifier "); - break; - } - case CERT_KEY_PROV_HANDLE_PROP_ID: - { - printf("KEY PROVE HANDLE"); - break; - } - case CERT_KEY_PROV_INFO_PROP_ID: - { - printf("KEY PROV INFO PROP ID "); - break; - } - case CERT_SHA1_HASH_PROP_ID: - { - printf("SHA1 HASH identifier"); - break; - } - case CERT_MD5_HASH_PROP_ID: - { - printf("md5 hash identifier "); - break; - } - case CERT_KEY_CONTEXT_PROP_ID: - { - printf("KEY CONTEXT PROP identifier"); - break; - } - case CERT_KEY_SPEC_PROP_ID: - { - printf("KEY SPEC PROP identifier"); - break; - } - case CERT_ENHKEY_USAGE_PROP_ID: - { - printf("ENHKEY USAGE PROP identifier"); - break; - } - case CERT_NEXT_UPDATE_LOCATION_PROP_ID: - { - printf("NEXT UPDATE LOCATION PROP identifier"); - break; - } - case CERT_PVK_FILE_PROP_ID: - { - printf("PVK FILE PROP identifier "); - break; - } - case CERT_DESCRIPTION_PROP_ID: - { - printf("DESCRIPTION PROP identifier "); - break; - } - case CERT_ACCESS_STATE_PROP_ID: - { - printf("ACCESS STATE PROP identifier "); - break; - } - case CERT_SMART_CARD_DATA_PROP_ID: - { - printf("SMART_CARD DATA PROP identifier "); - break; - } - case CERT_EFS_PROP_ID: - { - printf("EFS PROP identifier "); - break; - } - case CERT_FORTEZZA_DATA_PROP_ID: - { - printf("FORTEZZA DATA PROP identifier "); - break; - } - case CERT_ARCHIVED_PROP_ID: - { - printf("ARCHIVED PROP identifier "); - break; - } - case CERT_KEY_IDENTIFIER_PROP_ID: - { - printf("KEY IDENTIFIER PROP identifier "); - break; - } - case CERT_AUTO_ENROLL_PROP_ID: - { - printf("AUTO ENROLL identifier. "); - break; - } - } // End switch. - - //------------------------------------------------------------------- - // Retrieve information on the property by first getting the - // property size. - // For more information, see CertGetCertificateContextProperty. - - if(CertGetCertificateContextProperty( - pCertContext, - dwPropId , - NULL, - &cbData)) - { - // Continue. - } - else - { - // If the first call to the function failed, - // exit to an error routine. - MyHandleError("Call #1 to GetCertContextProperty failed."); - } - //------------------------------------------------------------------- - // The call succeeded. Use the size to allocate memory - // for the property. - - if(pvData = (void*)malloc(cbData)) - { - // Memory is allocated. Continue. - } - else - { - // If memory allocation failed, exit to an error routine. - MyHandleError("Memory allocation failed."); - } - //---------------------------------------------------------------- - // Allocation succeeded. Retrieve the property data. - - if(CertGetCertificateContextProperty( - pCertContext, - dwPropId, - pvData, - &cbData)) - { - // The data has been retrieved. Continue. - } - else - { - // If an error occurred in the second call, - // exit to an error routine. - MyHandleError("Call #2 failed."); - } - //--------------------------------------------------------------- - // Show the results. - - printf("The Property Content is %d \n", pvData); - - //---------------------------------------------------------------- - // Free the certificate context property memory. - - free(pvData); - } // End inner while. - } // End outer while. - -#endif - - //------------------------------------------------------------------- - // Select a new certificate by using the user interface. - - if(!(pCertContext = CryptUIDlgSelectCertificateFromStore(hCertStore, NULL, NULL, NULL, CRYPTUI_SELECT_LOCATION_COLUMN, 0, NULL))) - { - MyHandleError("Select UI failed." ); - } - - if (false) - { - bool bRes = true; - bRes = Sign(pCertContext, NSFile::GetProcessDirectory() + L"/test.xml", NSFile::GetProcessDirectory() + L"/result.txt"); - bRes = Verify(pCertContext, NSFile::GetProcessDirectory() + L"/test.xml", NSFile::GetProcessDirectory() + L"/result.txt"); - - CXmlSigner oSigner(pCertContext); - std::string sCertBase64 = oSigner.GetCertificateBase64(); - std::string sCertHash = oSigner.GetCertificateHash(); - } - - //SignDocument(NSFile::GetProcessDirectory() + L"/ImageStamp", pCertContext, L"{39B6B9C7-60AD-45A2-9F61-40C74A24042E}"); - SignDocument(L"D:\\555", pCertContext, L"{9792D33F-AB37-4E5B-A465-481B9465818B}"); - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - CertFreeCertificateContext(pCertContext); - CertCloseStore(hCertStore,0); - printf("The function completed successfully. \n"); -} - -void MyHandleError(LPTSTR psz) -{ - _ftprintf(stderr, TEXT("An error occurred in the program. \n")); - _ftprintf(stderr, TEXT("%s\n"), psz); - _ftprintf(stderr, TEXT("Error number %x.\n"), GetLastError()); - _ftprintf(stderr, TEXT("Program terminating. \n")); - exit(1); -} // End of MyHandleError. - -bool Sign(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile) -{ - std::string sXmlPrepare = CXmlCanonicalizator::Execute(sFileXml, XML_C14N_1_0); - - CXmlSigner oSigner(pCertContext); - std::string sXmlSigned = oSigner.Sign(sXmlPrepare); - - NSFile::CFileBinary oFile; - oFile.CreateFileW(sSignatureFile); - oFile.WriteFile((BYTE*)sXmlSigned.c_str(), (DWORD)sXmlSigned.length()); - oFile.CloseFile(); - - return (!sXmlSigned.empty()); -} - -bool Verify(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile) -{ - std::string sXmlUtf8; - NSFile::CFileBinary::ReadAllTextUtf8A(sFileXml, sXmlUtf8); - - std::string sXmlUtf8Prepare = CXmlCanonicalizator::Execute(sXmlUtf8, XML_C14N_1_0); - - std::string sXmlUtf8Signature; - NSFile::CFileBinary::ReadAllTextUtf8A(sSignatureFile, sXmlUtf8Signature); - - if (sXmlUtf8Prepare.empty() || sXmlUtf8Signature.empty()) - return false; - - CXmlSigner oSigner(pCertContext); - return (TRUE == oSigner.Verify(sXmlUtf8Prepare, sXmlUtf8Signature)); -} - -class COOXMLSigner -{ -public: - PCCERT_CONTEXT m_context; - std::wstring m_sFolder; - - CXmlSigner* m_signer; - - std::wstring m_date; - std::map m_content_types; - std::vector m_rels; - std::vector m_files; - - NSStringUtils::CStringBuilderA m_signed_info; - - std::wstring m_image_valid; - std::wstring m_image_invalid; - - std::wstring m_guid; - -public: - class COOXMLRelationship - { - public: - std::wstring rid; - std::wstring type; - std::wstring target; - std::wstring target_mode; - - public: - - COOXMLRelationship() - { - } - - COOXMLRelationship(XmlUtils::CXmlNode& node) - { - rid = node.GetAttribute("Id"); - type = node.GetAttribute("Type"); - target = node.GetAttribute("Target"); - - CheckTargetMode(); - } - - std::wstring GetXml() - { - NSStringUtils::CStringBuilder builder; - builder.WriteString(L""); - return builder.GetData(); - } - - static bool Compare(const COOXMLRelationship& i, const COOXMLRelationship& j) - { - return i.rid < j.rid; - } - - protected: - - void CheckTargetMode() - { - if (0 == target.find(L"http") || 0 == target.find(L"www") || 0 == target.find(L"ftp")) - target_mode = L"External"; - else - target_mode = L"Internal"; - } - }; - - class COOXMLRelationships - { - public: - std::vector rels; - - public: - - COOXMLRelationships() - { - } - - COOXMLRelationships(std::wstring& file) - { - XmlUtils::CXmlNode oNode; - if (!oNode.FromXmlFile(file)) - return; - - XmlUtils::CXmlNodes oNodes; - if (!oNode.GetNodes(L"Relationship", oNodes)) - return; - - int nCount = oNodes.GetCount(); - for (int i = 0; i < nCount; ++i) - { - XmlUtils::CXmlNode oRel; - oNodes.GetAt(i, oRel); - rels.push_back(COOXMLRelationship(oRel)); - } - } - - std::wstring GetXml() - { - NSStringUtils::CStringBuilder builder; - - builder.WriteString(L""); - - // sort by rId - std::sort(rels.begin(), rels.end(), COOXMLRelationship::Compare); - - for (std::vector::iterator i = rels.begin(); i != rels.end(); i++) - builder.WriteString(i->GetXml()); - - builder.WriteString(L""); - - return builder.GetData(); - } - - std::wstring GetTransforms() - { - NSStringUtils::CStringBuilder builder; - - builder.WriteString(L""); - - for (std::vector::iterator i = rels.begin(); i != rels.end(); i++) - { - builder.WriteString(L"rid); - builder.WriteString(L"\" />"); - } - - builder.WriteString(L""); - - return builder.GetData(); - } - - void CheckOriginSigs(std::wstring& file) - { - int rId = 0; - std::vector::iterator i = rels.begin(); - while (i != rels.end()) - { - if (0 == i->target.find(L"_xmlsignatures/")) - return; - - std::wstring rid = i->rid; - rid = rid.substr(3); - - int nTemp = std::stoi(rid); - - if (nTemp > rId) - rId = nTemp; - - i++; - } - - 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(); - } - }; - -public: - COOXMLSigner(const std::wstring& sFolder, PCCERT_CONTEXT pContext) - { - m_sFolder = sFolder; - m_context = pContext; - m_signer = new CXmlSigner(pContext); - - m_date = L"2017-04-21T08:30:21Z"; - - m_signed_info.WriteString(""); - m_signed_info.WriteString(""); - } - ~COOXMLSigner() - { - RELEASEOBJECT(m_signer); - } - - std::wstring GetReference(const std::wstring& file, const std::wstring& content_type) - { - std::wstring sXml = L""; - sXml += L""; - sXml += L""; - sXml += UTF8_TO_U(m_signer->GetHash(m_sFolder + file)); - sXml += L""; - sXml += L""; - return sXml; - } - - std::string GetHashXml(const std::wstring& xml) - { - std::string sXmlSigned = U_TO_UTF8(xml); - sXmlSigned = CXmlCanonicalizator::Execute(sXmlSigned, XML_C14N_1_0); - return m_signer->GetHash(sXmlSigned); - } - - std::string GetReferenceMain(const std::wstring& xml, const std::wstring& id, const bool& isCannon = true) - { - std::wstring sXml1 = L""; - else - sXml1 += (L" Id=\"" + id + L"\">"); - sXml1 += xml; - sXml1 += L""; - - std::string sHash = GetHashXml(sXml1); - - std::string sRet; - if (isCannon) - sRet = ""; - - sRet += ("" + sHash + ""); - - return sRet; - } - - std::wstring GetImageBase64(const std::wstring& file) - { - BYTE* pData = NULL; - DWORD dwLen = 0; - if (!NSFile::CFileBinary::ReadAllBytes(file, &pData, dwLen)) - return L""; - - char* pDataC = NULL; - int nLen = 0; - NSFile::CBase64Converter::Encode(pData, (int)dwLen, pDataC, nLen, NSBase64::B64_BASE64_FLAG_NOCRLF); - - std::wstring sReturn = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pDataC, (LONG)nLen, FALSE); - - RELEASEARRAYOBJECTS(pData); - RELEASEARRAYOBJECTS(pDataC); - - return sReturn; - } - - std::wstring GetRelsReference(const std::wstring& file) - { - COOXMLRelationships oRels(m_sFolder + file); - - if (L"/_rels/.rels" == file) - { - oRels.CheckOriginSigs(m_sFolder + file); - - // удалим все лишнее - std::vector::iterator i = oRels.rels.begin(); - while (i != oRels.rels.end()) - { - if (0 == i->target.find(L"docProps/")) - i = oRels.rels.erase(i); - else if (0 == i->target.find(L"_xmlsignatures/")) - i = oRels.rels.erase(i); - else - i++; - } - } - - NSStringUtils::CStringBuilder builder; - builder.WriteString(L""); - builder.WriteString(oRels.GetTransforms()); - builder.WriteString(L""); - - std::wstring sXml = oRels.GetXml(); - std::string sHash = GetHashXml(sXml); - - std::wstring sHashW = UTF8_TO_U(sHash); - builder.WriteString(sHashW); - - builder.WriteString(L""); - - return builder.GetData(); - } - - int GetCountSigns(const std::wstring& file) - { - if (!NSFile::CFileBinary::Exists(file)) - { - std::wstring sRels = L"\ -\ -\ -"; - - NSFile::CFileBinary::SaveToFile(file, sRels, false); - return 1; - } - - XmlUtils::CXmlNode oNode; - oNode.FromXmlFile(file); - - XmlUtils::CXmlNodes oNodes; - oNode.GetNodes(L"Relationship", oNodes); - - int rId = oNodes.GetCount() + 1; - - std::string sXmlA; - NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA); - - std::string::size_type pos = sXmlA.rfind(""); - if (pos == std::string::npos) - return 1; - - 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(); - - return rId; - } - - void ParseContentTypes() - { - std::wstring file = m_sFolder + L"/[Content_Types].xml"; - XmlUtils::CXmlNode oNode; - oNode.FromXmlFile(file); - - XmlUtils::CXmlNodes nodesDefaults; - oNode.GetNodes(L"Default", nodesDefaults); - - XmlUtils::CXmlNodes nodesOverrides; - oNode.GetNodes(L"Override", nodesOverrides); - - int nCount = nodesDefaults.GetCount(); - for (int i = 0; i < nCount; ++i) - { - XmlUtils::CXmlNode node; - nodesDefaults.GetAt(i, node); - - m_content_types.insert(std::pair(node.GetAttribute("Extension"), node.GetAttribute("ContentType"))); - } - - nCount = nodesOverrides.GetCount(); - for (int i = 0; i < nCount; ++i) - { - XmlUtils::CXmlNode node; - nodesOverrides.GetAt(i, node); - - m_content_types.insert(std::pair(node.GetAttribute("PartName"), node.GetAttribute("ContentType"))); - } - } - - void Parse() - { - // 1) Parse Content_Types.xml - ParseContentTypes(); - - // 2) Parse files in directory - std::vector files = NSDirectory::GetFiles(m_sFolder, true); - - // 3) Check each file - std::wstring sFolder = m_sFolder; - NSStringUtils::string_replace(sFolder, L"\\", L"/"); - for (std::vector::iterator i = files.begin(); i != files.end(); i++) - { - std::wstring sCheckFile = *i; - NSStringUtils::string_replace(sCheckFile, L"\\", L"/"); - - if (0 != sCheckFile.find(sFolder)) - continue; - - // make cool filename - sCheckFile = sCheckFile.substr(sFolder.length()); - - // check needed file - if (0 == sCheckFile.find(L"/_xmlsignatures") || - 0 == sCheckFile.find(L"/docProps") || - 0 == sCheckFile.find(L"/[Content_Types].xml")) - continue; - - // check rels and add to needed array - std::wstring::size_type posExt = sCheckFile.rfind(L"."); - if (std::wstring::npos == posExt) - continue; - - std::wstring sExt = sCheckFile.substr(posExt + 1); - if (sExt == L"rels") - m_rels.push_back(sCheckFile); - else - m_files.push_back(sCheckFile); - } - - std::sort(m_rels.begin(), m_rels.end()); - std::sort(m_files.begin(), m_files.end()); - } - - void WriteRelsReferences(NSStringUtils::CStringBuilder& builder) - { - for (std::vector::iterator i = m_rels.begin(); i != m_rels.end(); i++) - { - builder.WriteString(GetRelsReference(*i)); - } - } - - void WriteFilesReferences(NSStringUtils::CStringBuilder& builder) - { - for (std::vector::iterator i = m_files.begin(); i != m_files.end(); i++) - { - std::wstring sFile = *i; - std::wstring sContentType = L"application/xml"; - - std::map::iterator _find = m_content_types.find(sFile); - if (_find != m_content_types.end()) - { - sContentType = _find->second; - } - else - { - std::wstring::size_type posExt = sFile.rfind(L"."); - if (std::wstring::npos != posExt) - { - std::wstring sExt = sFile.substr(posExt + 1); - - _find = m_content_types.find(sExt); - if (_find != m_content_types.end()) - sContentType = _find->second; - } - } - - builder.WriteString(GetReference(sFile, sContentType)); - } - } - - void WriteManifest(NSStringUtils::CStringBuilder& builder) - { - builder.WriteString(L""); - WriteRelsReferences(builder); - WriteFilesReferences(builder); - builder.WriteString(L""); - } - - void CorrectContentTypes(int nCountSigsNeeds) - { - std::wstring file = m_sFolder + L"/[Content_Types].xml"; - XmlUtils::CXmlNode oNode; - oNode.FromXmlFile(file); - - XmlUtils::CXmlNodes nodesDefaults; - oNode.GetNodes(L"Default", nodesDefaults); - - XmlUtils::CXmlNodes nodesOverrides; - oNode.GetNodes(L"Override", nodesOverrides); - - std::string sAddition = ""; - - bool bIsSigsExist = false; - int nCount = nodesDefaults.GetCount(); - for (int i = 0; i < nCount; ++i) - { - XmlUtils::CXmlNode node; - nodesDefaults.GetAt(i, node); - - if ("sigs" == node.GetAttributeA("Extension") && - "application/vnd.openxmlformats-package.digital-signature-origin" == node.GetAttributeA("ContentType")) - { - bIsSigsExist = true; - break; - } - } - - if (!bIsSigsExist) - sAddition += ""; - - int nCountSigs = 0; - nCount = nodesOverrides.GetCount(); - for (int i = 0; i < nCount; ++i) - { - XmlUtils::CXmlNode node; - nodesOverrides.GetAt(i, node); - - if ("application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml" == node.GetAttributeA("ContentType")) - { - ++nCountSigs; - } - } - - for (int i = nCountSigs; i < nCountSigsNeeds; ++i) - { - sAddition += ""; - } - - std::string sXmlA; - NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA); - - std::string::size_type pos = sXmlA.rfind(""); - if (pos == std::string::npos) - return; - - std::string sRet = sXmlA.substr(0, pos); - sRet += sAddition; - sRet += ""; - - NSFile::CFileBinary::Remove(file); - - NSFile::CFileBinary oFile; - oFile.CreateFileW(file); - oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length()); - oFile.CloseFile(); - } - - void SetGuid(const std::wstring& guid) - { - m_guid = guid; - } - void SetImageValid(const std::wstring& file) - { - m_image_valid = GetImageBase64(file); - } - void SetImageInvalid(const std::wstring& file) - { - m_image_invalid = GetImageBase64(file); - } - - std::wstring GeneratePackageObject() - { - NSStringUtils::CStringBuilder builder; - WriteManifest(builder); - - builder.WriteString(L""); - builder.WriteString(L""); - builder.WriteString(L"YYYY-MM-DDThh:mm:ssTZD"); - builder.WriteString(L""); - builder.WriteString(m_date); - builder.WriteString(L""); - builder.WriteString(L""); - - std::wstring sXml = builder.GetData(); - - m_signed_info.WriteString(""); - m_signed_info.WriteString(GetReferenceMain(sXml, L"idPackageObject", false)); - m_signed_info.WriteString(""); - - return (L"" + sXml + L""); - } - std::wstring GenerateOfficeObject() - { - NSStringUtils::CStringBuilder builder; - - builder.WriteString(L""); - builder.WriteString(L""); - builder.WriteString(L""); - builder.WriteString(m_guid); - builder.WriteString(L""); - builder.WriteString(L""); - builder.WriteString(L""); - builder.WriteString(m_image_valid); - builder.WriteString(L""); - builder.WriteString(L"\ -10.0\ -16.0\ -16.0\ -2\ -1680\ -1050\ -32\ -{00000000-0000-0000-0000-000000000000}\ -\ -9\ -2\ -\ -\ -"); - - m_signed_info.WriteString(""); - m_signed_info.WriteString(GetReferenceMain(builder.GetData(), L"idOfficeObject", false)); - m_signed_info.WriteString(""); - - return (L"" + builder.GetData() + L""); - } - - std::wstring GenerateImageObject() - { - if (m_image_valid.empty()) - return L""; - - m_signed_info.WriteString(""); - m_signed_info.WriteString(GetReferenceMain(m_image_valid, L"idValidSigLnImg", false)); - m_signed_info.WriteString(""); - - m_signed_info.WriteString(""); - m_signed_info.WriteString(GetReferenceMain(m_image_invalid, L"idInvalidSigLnImg", false)); - m_signed_info.WriteString(""); - - return (L"" + m_image_valid + L"" + m_image_invalid + L""); - } - - std::wstring GenerateSignPropertiesObject() - { - DWORD dwNameLen = CertGetNameStringW(m_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0); - wchar_t* pNameData = new wchar_t[dwNameLen]; - CertGetNameStringW(m_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, pNameData, dwNameLen); - std::wstring sName(pNameData); - RELEASEARRAYOBJECTS(pNameData); - - int nNumberLen = (int)m_context->pCertInfo->SerialNumber.cbData; - BYTE* pNumberData = new BYTE[nNumberLen]; - CXmlSigner::ConvertEndian(m_context->pCertInfo->SerialNumber.pbData, pNumberData, (DWORD)nNumberLen); - CBigInteger oInteger(pNumberData, nNumberLen); - delete[] pNumberData; - - std::string sKeyA = oInteger.ToString(); - std::wstring sKey = UTF8_TO_U(sKeyA); - - std::wstring sXml = (L"\ -" + m_date + L"\ -\ -\ -\ -\ -MJJT2Y0iMxaPGVXBmOLb9bY60pA=\ -\ -\ -CN=" + sName + L"\ -" + sKey + L"\ -\ -\ -\ -\ -\ -\ -"); - - std::wstring sSignedXml = L""; - sSignedXml += sXml; - sSignedXml += L""; - - std::string sXmlTmp = CXmlCanonicalizator::Execute(U_TO_UTF8(sSignedXml), XML_C14N_1_0); - - m_signed_info.WriteString(""); - m_signed_info.WriteString(""); - m_signed_info.WriteString(""); - m_signed_info.WriteString(m_signer->GetHash(sXmlTmp)); - m_signed_info.WriteString(""); - - return (L"\ -" + sXml + L""); - } - - int AddSignatureReference() - { - std::wstring sDirectory = m_sFolder + L"/_xmlsignatures"; - - if (!NSDirectory::Exists(sDirectory)) - NSDirectory::CreateDirectory(sDirectory); - - if (!NSFile::CFileBinary::Exists(sDirectory + L"/origin.sigs")) - { - NSFile::CFileBinary oFile; - oFile.CreateFileW(sDirectory + L"/origin.sigs"); - oFile.CloseFile(); - } - - if (!NSDirectory::Exists(sDirectory + L"/_rels")) - NSDirectory::CreateDirectory(sDirectory + L"/_rels"); - - int nSignNum = GetCountSigns(sDirectory + L"/_rels/origin.sigs.rels"); - - CorrectContentTypes(nSignNum); - - return nSignNum; - } - - void Sign() - { - Parse(); - - std::string sSignedData; - - NSStringUtils::CStringBuilder builderMain; - - builderMain.WriteString(GeneratePackageObject()); - builderMain.WriteString(GenerateOfficeObject()); - builderMain.WriteString(GenerateSignPropertiesObject()); - builderMain.WriteString(GenerateImageObject()); - - std::string sSignedInfoData = m_signed_info.GetData(); - std::string sSignedXml = "" + sSignedInfoData + ""; - sSignedXml = CXmlCanonicalizator::Execute(sSignedXml, XML_C14N_1_0); - sSignedXml = m_signer->Sign(sSignedXml); - - NSStringUtils::CStringBuilder builderResult; - builderResult.WriteString(L""); - builderResult.WriteString(UTF8_TO_U(sSignedInfoData)); - builderResult.WriteString(L""); - builderResult.WriteString(L""); - builderResult.WriteString(UTF8_TO_U(sSignedXml)); - builderResult.WriteString(L""); - builderResult.WriteString(L""); - builderResult.WriteString(UTF8_TO_U(m_signer->GetCertificateBase64())); - builderResult.WriteString(L""); - - builderResult.Write(builderMain); - builderResult.WriteString(L""); - - int nSignNum = AddSignatureReference(); - - NSFile::CFileBinary::SaveToFile(m_sFolder + L"/_xmlsignatures/sig" + std::to_wstring(nSignNum) + L".xml", builderResult.GetData(), false); - } -}; - -bool SignDocument(std::wstring sFolderOOXML, PCCERT_CONTEXT pCertContext, std::wstring sign_id) -{ - COOXMLSigner oOOXMLSigner(sFolderOOXML, pCertContext); - - oOOXMLSigner.SetGuid(sign_id); + oOOXMLSigner.SetGuid(sSignId); oOOXMLSigner.SetImageValid(NSFile::GetProcessDirectory() + L"/../../../resources/valid.png"); oOOXMLSigner.SetImageInvalid(NSFile::GetProcessDirectory() + L"/../../../resources/invalid.png"); oOOXMLSigner.Sign(); - return true; }