Commit 10b9e9e5 authored by Oleg Korshul's avatar Oleg Korshul

verify ooxml file. developing...

parent 1beb5440
......@@ -20,6 +20,8 @@ private:
std::string m_sImageValidBase64;
std::string m_sImageInvalidBase64;
std::wstring m_sFolder;
private:
XmlUtils::CXmlNode m_node; // signature file
......@@ -50,16 +52,23 @@ private:
return *this;
}
CXmlStackNamespaces GetById(const std::string& id)
CXmlStackNamespaces GetById(const std::string& id, const bool& isNameUse = false)
{
return GetByIdRec(*this, id);
return GetByIdRec(*this, id, isNameUse);
}
CXmlStackNamespaces GetByIdRec(CXmlStackNamespaces& stack, const std::string& id)
CXmlStackNamespaces GetByIdRec(CXmlStackNamespaces& stack, const std::string& id, const bool& isNameUse = false)
{
if (stack.m_node.GetAttributeA("Id") == id)
return stack;
if (isNameUse)
{
std::string sName = U_TO_UTF8((stack.m_node.GetName()));
if (sName == id)
return stack;
}
CXmlStackNamespaces ret = stack;
std::vector<std::wstring> _names;
......@@ -152,7 +161,7 @@ public:
public:
void Check()
{
// 1) get cert
// 1) Certificate
XmlUtils::CXmlNode oNodeCert = m_node.ReadNode(L"KeyInfo").ReadNode(L"X509Data").ReadNode(L"X509Certificate");
if (!oNodeCert.IsValid())
{
......@@ -166,28 +175,212 @@ public:
return;
}
// 2) Objects
// 2) Check files (Manifect)
XmlUtils::CXmlNode nodeManifect = GetObjectById("idPackageObject");
if (!nodeManifect.IsValid())
{
m_valid = OOXML_SIGNATURE_INVALID;
return;
}
XmlUtils::CXmlNodes nodesManifestRefs = nodeManifect.ReadNode(L"Manifest").GetNodes(L"Reference");
int nRefsCount = nodesManifestRefs.GetCount();
for (int i = 0; i < nRefsCount; i++)
{
XmlUtils::CXmlNode tmp;
nodesManifestRefs.GetAt(i, tmp);
m_valid = CheckManifestReference(tmp);
if (OOXML_SIGNATURE_VALID != m_valid)
return;
}
// 3) Images
XmlUtils::CXmlNode nodeImageValid = GetObjectById("idValidSigLnImg");
if (nodeImageValid.IsValid())
m_sImageValidBase64 = U_TO_UTF8(nodeImageValid.GetText());
XmlUtils::CXmlNode nodeImageInvalid = GetObjectById("idInvalidSigLnImg");
if (nodeImageInvalid.IsValid())
m_sImageInvalidBase64 = U_TO_UTF8(nodeImageInvalid.GetText());
// 4) Objects
XmlUtils::CXmlNodes nodesReferences;
m_node.ReadNode(L"SignedInfo").GetNodes(L"Reference", nodesReferences);
nRefsCount = nodesReferences.GetCount();
for (int i = 0; i < nRefsCount; i++)
{
XmlUtils::CXmlNode tmp;
nodesReferences.GetAt(i, tmp);
m_valid = CheckObjectReference(tmp);
if (OOXML_SIGNATURE_VALID != m_valid)
return;
}
// 5) Check signature
CXmlStackNamespaces stack(m_node);
int nCount = nodesReferences.GetCount();
for (int i = 0; i < nCount; i++)
CXmlStackNamespaces stackRes = stack.GetById("SignedInfo", true);
std::string sXml = stackRes.GetXml();
std::string sCanonicalizationMethod = m_node.ReadNode(L"SignedInfo").ReadNode(L"CanonicalizationMethod").GetAttributeA("Algorithm");
std::string sSignatureMethod = m_node.ReadNode(L"SignedInfo").ReadNode(L"CanonicalizationMethod").GetAttributeA("Algorithm");
int nSignatureMethod = ICertificate::GetOOXMLHashAlg(sSignatureMethod);
if (OOXML_HASH_ALG_INVALID == nSignatureMethod)
{
XmlUtils::CXmlNode nodeRef;
nodesReferences.GetAt(i, nodeRef);
m_valid = OOXML_SIGNATURE_NOTSUPPORTED;
return;
}
IXmlTransform* pCanonicalizationMethodTransform = IXmlTransform::GetFromType(sCanonicalizationMethod);
if (NULL == pCanonicalizationMethodTransform)
{
m_valid = OOXML_SIGNATURE_NOTSUPPORTED;
return;
}
std::string sId = nodeRef.GetAttributeA("URI");
if (0 == sId.find("#"))
sId = sId.substr(1);
std::string sSignatureCalcValue = pCanonicalizationMethodTransform->Transform(sXml);
RELEASEOBJECT(pCanonicalizationMethodTransform);
CXmlStackNamespaces _stack = stack.GetById(sId);
std::string sTmp = _stack.GetXml();
XML_UNUSED(sTmp);
std::string sSignatureValue = U_TO_UTF8((m_node.ReadValueString(L"SignatureValue")));
if (sSignatureCalcValue != sSignatureValue)
m_valid = OOXML_SIGNATURE_INVALID;
}
XmlUtils::CXmlNode GetObjectById(std::string sId)
{
XmlUtils::CXmlNodes oNodes = m_node.GetNodes(L"Object");
int nCount = oNodes.GetCount();
for (int i = 0; i < nCount; i++)
{
XmlUtils::CXmlNode tmp;
oNodes.GetAt(i, tmp);
if (sId == tmp.GetAttributeA("Id"))
return tmp;
}
XmlUtils::CXmlNode ret;
return ret;
}
friend class COOXMLVerifier;
private:
int CheckManifestReference(XmlUtils::CXmlNode& node)
{
std::wstring sFile = node.GetAttribute("URI");
std::wstring::size_type nPos = sFile.find(L"?");
if (nPos == std::wstring::npos)
return OOXML_SIGNATURE_INVALID;
sFile = sFile.substr(0, nPos);
sFile = m_sFolder + sFile;
if (!NSFile::CFileBinary::Exists(sFile))
return OOXML_SIGNATURE_INVALID;
XmlUtils::CXmlNode nodeMethod = node.ReadNode(L"DigestMethod");
if (!nodeMethod.IsValid())
return OOXML_SIGNATURE_INVALID;
int nAlg = ICertificate::GetOOXMLHashAlg(nodeMethod.GetAttributeA("Algorithm"));
if (OOXML_HASH_ALG_INVALID == nAlg)
return OOXML_SIGNATURE_NOTSUPPORTED;
std::string sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
std::string sCalcValue = "";
XmlUtils::CXmlNode nodeTransform = node.ReadNode(L"Transforms");
if (!nodeTransform.IsValid())
{
// simple hash
sCalcValue = m_cert->GetHash(sFile, nAlg);
sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
}
else
{
// XML
CXmlTransforms oTransforms(nodeTransform);
if (!oTransforms.GetValid())
return OOXML_SIGNATURE_NOTSUPPORTED;
std::string sXml;
NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sXml);
sXml = oTransforms.Transform(sXml);
sCalcValue = m_cert->GetHash(sXml, nAlg);
sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
}
if (sCalcValue != sValue)
return OOXML_SIGNATURE_INVALID;
return OOXML_SIGNATURE_VALID;
}
int CheckObjectReference(XmlUtils::CXmlNode& node)
{
std::string sURI = node.GetAttributeA("URI");
if ("" == sURI)
return OOXML_SIGNATURE_INVALID;
if (0 == sURI.find("#"))
sURI = sURI.substr(1);
std::string sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
CXmlTransforms oTransforms;
CXmlTransformC14N* pTransform = new CXmlTransformC14N();
pTransform->CheckC14NTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
oTransforms.AddTransform(pTransform);
#if 0
XmlUtils::CXmlNode nodeTransform = node.ReadNode(L"Transforms");
if (!nodeTransform.IsValid())
{
// simple hash
sCalcValue = m_cert->GetHash(sFile, nAlg);
sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
}
else
{
// XML
CXmlTransforms oTransforms(nodeTransform);
if (!oTransforms.GetValid())
return OOXML_SIGNATURE_NOTSUPPORTED;
std::string sXml;
NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sXml);
sXml = oTransforms.Transform(sXml);
sCalcValue = m_cert->GetHash(sXml, nAlg);
sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
}
#endif
CXmlStackNamespaces stack(m_node);
CXmlStackNamespaces stackRes = stack.GetById(sURI);
std::string sXml = stackRes.GetXml();
sXml = oTransforms.Transform(sXml);
XmlUtils::CXmlNode nodeMethod = node.ReadNode(L"DigestMethod");
if (!nodeMethod.IsValid())
return OOXML_SIGNATURE_INVALID;
int nAlg = ICertificate::GetOOXMLHashAlg(nodeMethod.GetAttributeA("Algorithm"));
std::string sCalcValue = m_cert->GetHash(sXml, nAlg);
if (sCalcValue != sValue)
return OOXML_SIGNATURE_INVALID;
return OOXML_SIGNATURE_VALID;
}
};
class COOXMLVerifier
......@@ -229,6 +422,7 @@ public:
COOXMLSignature* pSignature = new COOXMLSignature();
pSignature->m_node = nodeSig;
pSignature->m_sFolder = m_sFolder;
pSignature->Check();
m_arSignatures.push_back(pSignature);
......
......@@ -110,8 +110,9 @@ public:
virtual std::string Transform(const std::string& xml)
{
// TODO
if (-1 == m_mode)
return xml;
return CXmlCanonicalizator::Execute(xml, m_mode, m_comments);
}
virtual void LoadFromXml(XmlUtils::CXmlNode& node)
......@@ -148,6 +149,11 @@ protected:
bool m_valid;
public:
CXmlTransforms()
{
m_valid = true;
}
CXmlTransforms(XmlUtils::CXmlNode& node)
{
m_valid = true;
......@@ -181,6 +187,25 @@ public:
m_transforms.clear();
}
bool GetValid()
{
return m_valid;
}
std::string Transform(const std::string& xml)
{
std::string sResult = xml;
for (std::vector<IXmlTransform*>::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
{
sResult = (*i)->Transform(sResult);
}
return sResult;
}
void AddTransform(IXmlTransform* transform)
{
m_transforms.push_back(transform);
}
};
#endif //_XML_TRANSFORM_H_
......@@ -37,7 +37,10 @@ void main(void)
for (std::vector<COOXMLSignature*>::iterator i = oVerifier.m_arSignatures.begin(); i != oVerifier.m_arSignatures.end(); i++)
{
COOXMLSignature* pSign = *i;
pSign->Check();
int nRes = pSign->GetValid();
XML_UNUSED(pSign);
XML_UNUSED(nRes);
}
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