Commit 9b4b7a26 authored by Oleg Korshul's avatar Oleg Korshul

verify ooxml file. developing...

parent 4d688b39
...@@ -305,6 +305,19 @@ namespace XmlUtils ...@@ -305,6 +305,19 @@ namespace XmlUtils
strValues.push_back (NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)p->second.c_str(), (long)p->second.length())); strValues.push_back (NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)p->second.c_str(), (long)p->second.length()));
} }
} }
template<typename T>
void ReadAllAttributesA(T& strNames, T& strValues)
{
if (!IsValid())
return;
std::map<std::string, std::string>::iterator p;
for (p = m_pBase->m_attributes.begin(); p != m_pBase->m_attributes.end(); ++p)
{
strNames.push_back(p->first);
strValues.push_back(p->second);
}
}
template <typename T> template <typename T>
void ReadNodeValueBase(const wchar_t* bsName, T& value) void ReadNodeValueBase(const wchar_t* bsName, T& value)
{ {
......
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
std::wstring sXml = L"<Reference URI=\"" + file + L"?ContentType=" + content_type + L"\">"; std::wstring sXml = L"<Reference URI=\"" + file + L"?ContentType=" + content_type + L"\">";
sXml += L"<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>"; sXml += L"<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>";
sXml += L"<DigestValue>"; sXml += L"<DigestValue>";
sXml += UTF8_TO_U(m_certificate->GetHash(m_sFolder + file)); sXml += UTF8_TO_U(m_certificate->GetHash(m_sFolder + file, OOXML_HASH_ALG_SHA1));
sXml += L"</DigestValue>"; sXml += L"</DigestValue>";
sXml += L"</Reference>"; sXml += L"</Reference>";
return sXml; return sXml;
...@@ -54,7 +54,7 @@ public: ...@@ -54,7 +54,7 @@ public:
{ {
std::string sXmlSigned = U_TO_UTF8(xml); std::string sXmlSigned = U_TO_UTF8(xml);
sXmlSigned = CXmlCanonicalizator::Execute(sXmlSigned, XML_C14N_1_0); sXmlSigned = CXmlCanonicalizator::Execute(sXmlSigned, XML_C14N_1_0);
return m_certificate->GetHash(sXmlSigned); return m_certificate->GetHash(sXmlSigned, OOXML_HASH_ALG_SHA1);
} }
std::string GetReferenceMain(const std::wstring& xml, const std::wstring& id, const bool& isCannon = true) std::string GetReferenceMain(const std::wstring& xml, const std::wstring& id, const bool& isCannon = true)
...@@ -491,7 +491,7 @@ Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-sign ...@@ -491,7 +491,7 @@ Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-sign
m_signed_info.WriteString("<Reference Type=\"http://uri.etsi.org/01903#SignedProperties\" URI=\"#idSignedProperties\">"); m_signed_info.WriteString("<Reference Type=\"http://uri.etsi.org/01903#SignedProperties\" URI=\"#idSignedProperties\">");
m_signed_info.WriteString("<Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>"); m_signed_info.WriteString("<Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
m_signed_info.WriteString("<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>"); m_signed_info.WriteString("<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>");
m_signed_info.WriteString(m_certificate->GetHash(sXmlTmp)); m_signed_info.WriteString(m_certificate->GetHash(sXmlTmp, OOXML_HASH_ALG_SHA1));
m_signed_info.WriteString("</DigestValue></Reference>"); m_signed_info.WriteString("</DigestValue></Reference>");
return (L"<Object><xd:QualifyingProperties xmlns:xd=\"http://uri.etsi.org/01903/v1.3.2#\" Target=\"#idPackageSignature\">\ return (L"<Object><xd:QualifyingProperties xmlns:xd=\"http://uri.etsi.org/01903/v1.3.2#\" Target=\"#idPackageSignature\">\
......
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
#define _XML_OOXMLVERIFIER_H_ #define _XML_OOXMLVERIFIER_H_
#include "./XmlCanonicalizator.h" #include "./XmlCanonicalizator.h"
#include "./XmlSignerBase.h"
#include "./XmlTransform.h" #include "./XmlTransform.h"
#include "./XmlCertificate.h"
#define OOXML_SIGNATURE_VALID 0 #define OOXML_SIGNATURE_VALID 0
#define OOXML_SIGNATURE_INVALID 1 #define OOXML_SIGNATURE_INVALID 1
#define OOXML_SIGNATURE_NOTSUPPORTED 2 #define OOXML_SIGNATURE_NOTSUPPORTED 2
#define OOXML_SIGNATURE_BAD 3
class COOXMLSignature class COOXMLSignature
{ {
...@@ -20,7 +21,98 @@ private: ...@@ -20,7 +21,98 @@ private:
std::string m_sImageInvalidBase64; std::string m_sImageInvalidBase64;
private: private:
XmlUtils::CXmlNode m_node; // signature file XmlUtils::CXmlNode m_node; // signature file
class CXmlStackNamespaces
{
public:
std::wstring m_namespaces;
XmlUtils::CXmlNode m_node;
public:
CXmlStackNamespaces(const CXmlStackNamespaces& src)
{
m_namespaces = src.m_namespaces;
m_node = src.m_node;
}
CXmlStackNamespaces()
{
}
CXmlStackNamespaces(const XmlUtils::CXmlNode& node)
{
m_node = node;
}
CXmlStackNamespaces& operator=(const CXmlStackNamespaces& src)
{
m_namespaces = src.m_namespaces;
m_node = src.m_node;
return *this;
}
CXmlStackNamespaces GetById(const std::string& id)
{
return GetByIdRec(*this, id);
}
CXmlStackNamespaces GetByIdRec(CXmlStackNamespaces& stack, const std::string& id)
{
if (stack.m_node.GetAttributeA("Id") == id)
return stack;
CXmlStackNamespaces ret = stack;
std::vector<std::wstring> _names;
std::vector<std::wstring> _values;
ret.m_node.ReadAllAttributes(_names, _values);
NSStringUtils::CStringBuilder oBuilder;
oBuilder.WriteString(L" ");
for (std::vector<std::wstring>::iterator i = _names.begin(), j = _values.begin(); i != _names.end(); i++, j++)
{
if (i->find(L"xmlns") == 0)
{
oBuilder.WriteString(*i);
oBuilder.WriteString(L"=\"");
oBuilder.WriteEncodeXmlString(*j);
oBuilder.WriteString(L"\"");
}
}
if (oBuilder.GetCurSize() != 1)
ret.m_namespaces += oBuilder.GetData();
XmlUtils::CXmlNodes oNodes;
if (stack.m_node.GetChilds(oNodes))
{
int nCount = oNodes.GetCount();
for (int i = 0; i < nCount; i++)
{
CXmlStackNamespaces _retRecursion = GetByIdRec(ret, id);
if (_retRecursion.m_node.IsValid())
return _retRecursion;
}
}
return CXmlStackNamespaces();
}
std::string GetXml()
{
std::wstring sXml = m_node.GetXml();
if (!m_namespaces.empty())
{
std::wstring sName = m_node.GetName();
std::wstring sXmlFind = L"<" + sName + L" ";
if (0 == sXml.find(sXmlFind))
sXml.replace(0, sXmlFind.length(), L"<" + sName + L" " + m_namespaces + L" ");
}
return U_TO_UTF8(sXml);
}
};
public: public:
COOXMLSignature() COOXMLSignature()
...@@ -59,10 +151,55 @@ public: ...@@ -59,10 +151,55 @@ public:
public: public:
void Check() void Check()
{ {
// 1) get cert
XmlUtils::CXmlNode oNodeCert = m_node.ReadNode(L"KeyInfo").ReadNode(L"X509Data").ReadNode(L"X509Certificate");
if (!oNodeCert.IsValid())
{
m_valid = OOXML_SIGNATURE_NOTSUPPORTED;
return;
}
m_cert = new CCertificate();
if (!m_cert->LoadFromBase64Data(U_TO_UTF8(oNodeCert.GetText())))
{
m_valid = OOXML_SIGNATURE_NOTSUPPORTED;
return;
}
} }
friend class COOXMLVerifier; friend class COOXMLVerifier;
private:
XmlUtils::CXmlNode GetById(const std::string& id)
{
return GetByIdRec(m_node, id);
}
XmlUtils::CXmlNode GetByIdRec(XmlUtils::CXmlNode& node, const std::string& id)
{
XmlUtils::CXmlNode retNode;
XmlUtils::CXmlNodes oNodes;
if (node.GetChilds(oNodes))
{
int nCount = oNodes.GetCount();
for (int i = 0; i < nCount; i++)
{
XmlUtils::CXmlNode _node;
oNodes.GetAt(i, _node);
if (_node.GetAttributeA("Id") == id)
return _node;
retNode = GetByIdRec(_node, id);
if (retNode.IsValid())
return retNode;
}
}
return retNode;
}
}; };
class COOXMLVerifier class COOXMLVerifier
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#include <vector> #include <vector>
#include <map> #include <map>
#define OOXML_HASH_ALG_SHA1 0
#define OOXML_HASH_ALG_INVALID 1
class ICertificate class ICertificate
{ {
public: public:
...@@ -27,17 +30,26 @@ public: ...@@ -27,17 +30,26 @@ public:
virtual std::string GetCertificateHash() = 0; virtual std::string GetCertificateHash() = 0;
public: public:
virtual std::string Sign(std::string sXml) = 0; virtual std::string Sign(std::string sXml) = 0;
virtual std::string GetHash(unsigned char* pData, unsigned int nSize) = 0; virtual std::string GetHash(unsigned char* pData, unsigned int nSize, int nAlg) = 0;
virtual std::string GetHash(std::string& sXml) = 0; virtual std::string GetHash(std::string& sXml, int nAlg) = 0;
virtual std::string GetHash(std::wstring& sXmlFile) = 0; virtual std::string GetHash(std::wstring& sXmlFile, int nAlg) = 0;
virtual bool Verify(std::string& sXml, std::string& sXmlSignature) = 0; virtual bool Verify(std::string& sXml, std::string& sXmlSignature, int nAlg) = 0;
virtual bool LoadFromBase64Data(const std::string& data) = 0; virtual bool LoadFromBase64Data(const std::string& data) = 0;
virtual int ShowCertificate() = 0; virtual int ShowCertificate() = 0;
public: public:
virtual bool ShowSelectDialog() = 0; virtual bool ShowSelectDialog() = 0;
static int GetOOXMLHashAlg(const std::string& sAlg)
{
if ("http://www.w3.org/2000/09/xmldsig#rsa-sha1" == sAlg ||
"http://www.w3.org/2000/09/xmldsig#sha1" == sAlg)
return OOXML_HASH_ALG_SHA1;
return OOXML_HASH_ALG_INVALID;
}
}; };
#endif // _XMLSIGNER_BASE_H_ #endif // _XMLSIGNER_BASE_H_
...@@ -93,7 +93,7 @@ public: ...@@ -93,7 +93,7 @@ public:
virtual std::string GetCertificateHash() virtual std::string GetCertificateHash()
{ {
return GetHash(m_context->pbCertEncoded, (unsigned int)m_context->cbCertEncoded); return GetHash(m_context->pbCertEncoded, (unsigned int)m_context->cbCertEncoded, OOXML_HASH_ALG_SHA1);
} }
public: public:
...@@ -166,8 +166,11 @@ public: ...@@ -166,8 +166,11 @@ public:
return sReturn; return sReturn;
} }
virtual std::string GetHash(unsigned char* pData, unsigned int nSize) virtual std::string GetHash(unsigned char* pData, unsigned int nSize, int nAlg)
{ {
if (nAlg == OOXML_HASH_ALG_INVALID)
return "";
BOOL bResult = TRUE; BOOL bResult = TRUE;
DWORD dwKeySpec = 0; DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL; HCRYPTHASH hHash = NULL;
...@@ -181,7 +184,7 @@ public: ...@@ -181,7 +184,7 @@ public:
if (!bResult) if (!bResult)
return ""; return "";
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); bResult = CryptCreateHash(hCryptProv, GetHashId(nAlg), 0, 0, &hHash);
if (!bResult) if (!bResult)
{ {
CryptReleaseContext(hCryptProv, 0); CryptReleaseContext(hCryptProv, 0);
...@@ -231,12 +234,12 @@ public: ...@@ -231,12 +234,12 @@ public:
return sReturn; return sReturn;
} }
virtual std::string GetHash(std::string& sXml) virtual std::string GetHash(std::string& sXml, int nAlg)
{ {
return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length()); return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length(), nAlg);
} }
virtual std::string GetHash(std::wstring& sXmlFile) virtual std::string GetHash(std::wstring& sXmlFile, int nAlg)
{ {
BYTE* pFileData = NULL; BYTE* pFileData = NULL;
DWORD dwFileDataLen = 0; DWORD dwFileDataLen = 0;
...@@ -245,13 +248,13 @@ public: ...@@ -245,13 +248,13 @@ public:
if (0 == dwFileDataLen) if (0 == dwFileDataLen)
return ""; return "";
std::string sReturn = GetHash(pFileData, dwFileDataLen); std::string sReturn = GetHash(pFileData, dwFileDataLen, nAlg);
RELEASEARRAYOBJECTS(pFileData); RELEASEARRAYOBJECTS(pFileData);
return sReturn; return sReturn;
} }
virtual bool Verify(std::string& sXml, std::string& sXmlSignature) virtual bool Verify(std::string& sXml, std::string& sXmlSignature, int nAlg)
{ {
DWORD dwKeySpec = 0; DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL; HCRYPTHASH hHash = NULL;
...@@ -263,7 +266,7 @@ public: ...@@ -263,7 +266,7 @@ public:
if (!bResult) if (!bResult)
return FALSE; return FALSE;
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash); bResult = CryptCreateHash(hCryptProv, GetHashId(nAlg), 0, 0, &hHash);
if (!bResult) if (!bResult)
{ {
...@@ -344,6 +347,17 @@ private: ...@@ -344,6 +347,17 @@ private:
for(BYTE* p = dst + size - 1; p >= dst; ++src, --p) for(BYTE* p = dst + size - 1; p >= dst; ++src, --p)
(*p) = (*src); (*p) = (*src);
} }
ALG_ID GetHashId(int nAlg)
{
switch (nAlg)
{
case OOXML_HASH_ALG_SHA1:
return CALG_SHA1;
default:
return CALG_SHA1;
}
}
}; };
#endif // _XMLSIGNER_MSCRYPTO_H_ #endif // _XMLSIGNER_MSCRYPTO_H_
...@@ -37,6 +37,7 @@ void main(void) ...@@ -37,6 +37,7 @@ void main(void)
for (std::vector<COOXMLSignature*>::iterator i = oVerifier.m_arSignatures.begin(); i != oVerifier.m_arSignatures.end(); i++) for (std::vector<COOXMLSignature*>::iterator i = oVerifier.m_arSignatures.begin(); i != oVerifier.m_arSignatures.end(); i++)
{ {
COOXMLSignature* pSign = *i; COOXMLSignature* pSign = *i;
XML_UNUSED(pSign);
} }
XML_UNUSED(nCount); XML_UNUSED(nCount);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment