xmlsecurity/inc/xmlsecurity/sigstruct.hxx | 2 + xmlsecurity/source/helper/ooxmlsecparser.cxx | 19 ++++++++- xmlsecurity/source/helper/ooxmlsecparser.hxx | 2 + xmlsecurity/source/helper/xsecctl.cxx | 53 +++++++++++++++++++++++++++ xmlsecurity/source/helper/xsecctl.hxx | 1 xmlsecurity/source/helper/xsecverify.cxx | 9 ++++ 6 files changed, 83 insertions(+), 3 deletions(-)
New commits: commit 3d004858944b1ec69446941e65f317ee78da172e Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Feb 12 09:50:42 2016 +0100 xmlsecurity OOXML export: write certificate digest With this, our signature on a DOCX file is accepted by Word as well. Change-Id: Ibd6bc77aa3f86a9b7f55f165383d1322ecb24f47 diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx index 756d80e..bdf1644 100644 --- a/xmlsecurity/source/helper/xsecctl.cxx +++ b/xmlsecurity/source/helper/xsecctl.cxx @@ -38,6 +38,9 @@ #include <rtl/ref.hxx> #include <unotools/datetime.hxx> #include <comphelper/ofopxmlhelper.hxx> +#include <sax/tools/converter.hxx> + +#include <certificate.hxx> namespace cssu = com::sun::star::uno; namespace cssl = com::sun::star::lang; @@ -1296,6 +1299,56 @@ void XSecController::exportOOXMLSignature(const uno::Reference<embed::XStorage>& pAttributeList->AddAttribute(ATTR_ID, "idSignedProperties"); xDocumentHandler->startElement(NSTAG_XD ":" TAG_SIGNEDPROPERTIES, uno::Reference<xml::sax::XAttributeList>(pAttributeList.get())); } + + xDocumentHandler->startElement("xd:SignedSignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->startElement("xd:SigningTime", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->characters(aSignatureTimeValue); + xDocumentHandler->endElement("xd:SigningTime"); + xDocumentHandler->startElement("xd:SigningCertificate", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->startElement("xd:Cert", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->startElement("xd:CertDigest", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + { + rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList()); + pAttributeList->AddAttribute(ATTR_ALGORITHM, ALGO_XMLDSIGSHA256); + xDocumentHandler->startElement("DigestMethod", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get())); + } + xDocumentHandler->endElement("DigestMethod"); + xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + + if (rInformation.ouCertDigest.isEmpty()) + { + uno::Reference<xml::crypto::XSecurityEnvironment> xEnvironment = m_xSecurityContext->getSecurityEnvironment(); + uno::Reference<security::XCertificate> xCertificate = xEnvironment->createCertificateFromAscii(rInformation.ouX509Certificate); + if (xmlsecurity::Certificate* pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCertificate.get())) + { + OUStringBuffer aBuffer; + sax::Converter::encodeBase64(aBuffer, pCertificate->getSHA256Thumbprint()); + xDocumentHandler->characters(aBuffer.makeStringAndClear()); + } + else + SAL_WARN("xmlsecurity.helper", "XCertificate implementation without an xmlsecurity::Certificate one"); + } + else + xDocumentHandler->characters(rInformation.ouCertDigest); + + xDocumentHandler->endElement("DigestValue"); + xDocumentHandler->endElement("xd:CertDigest"); + xDocumentHandler->startElement("xd:IssuerSerial", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->startElement("X509IssuerName", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->characters(rInformation.ouX509IssuerName); + xDocumentHandler->endElement("X509IssuerName"); + xDocumentHandler->startElement("X509SerialNumber", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->characters(rInformation.ouX509SerialNumber); + xDocumentHandler->endElement("X509SerialNumber"); + xDocumentHandler->endElement("xd:IssuerSerial"); + xDocumentHandler->endElement("xd:Cert"); + xDocumentHandler->endElement("xd:SigningCertificate"); + xDocumentHandler->startElement("xd:SignaturePolicyIdentifier", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->startElement("xd:SignaturePolicyImplied", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); + xDocumentHandler->endElement("xd:SignaturePolicyImplied"); + xDocumentHandler->endElement("xd:SignaturePolicyIdentifier"); + xDocumentHandler->endElement("xd:SignedSignatureProperties"); + xDocumentHandler->endElement(NSTAG_XD ":" TAG_SIGNEDPROPERTIES); xDocumentHandler->endElement(NSTAG_XD ":" TAG_QUALIFYINGPROPERTIES); xDocumentHandler->endElement(TAG_OBJECT); commit 89af47f2b3fba6692a1cea850159b2163a64db8b Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Feb 12 09:49:37 2016 +0100 xmlsecurity: import OOXML <xd:CertDigest> Another redundant field: it's the SHA-256 digest of the certificate data for OOXML, not used for ODF. We need to store it after import, as we no longer have the security environment at hand when we store the signature to the persistent storage. Change-Id: I3bcccb3c7c4f4178c0b267ce87777fba543f8716 diff --git a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx index f798b3b..e501239 100644 --- a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx +++ b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx @@ -81,6 +81,8 @@ struct SignatureInformation OUString ouDescription; /// The Id attribute of the <SignatureProperty> element that contains the <dc:description>. OUString ouDescriptionPropertyId; + /// OOXML certificate SHA-256 digest, empty for ODF. + OUString ouCertDigest; SignatureInformation( sal_Int32 nId ) { diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx index 2086d38..cc764b6 100644 --- a/xmlsecurity/source/helper/ooxmlsecparser.cxx +++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx @@ -21,6 +21,7 @@ OOXMLSecParser::OOXMLSecParser(XSecController* pXSecController) ,m_bInSignatureComments(false) ,m_bInX509IssuerName(false) ,m_bInX509SerialNumber(false) + ,m_bInCertDigest(false) ,m_bReferenceUnresolved(false) { } @@ -77,7 +78,7 @@ throw (xml::sax::SAXException, uno::RuntimeException, std::exception) } } } - else if (rName == "DigestValue") + else if (rName == "DigestValue" && !m_bInCertDigest) { m_aDigestValue.clear(); m_bInDigestValue = true; @@ -112,6 +113,11 @@ throw (xml::sax::SAXException, uno::RuntimeException, std::exception) m_aX509SerialNumber.clear(); m_bInX509SerialNumber = true; } + else if (rName == "xd:CertDigest") + { + m_aCertDigest.clear(); + m_bInCertDigest = true; + } if (m_xNextHandler.is()) m_xNextHandler->startElement(rName, xAttribs); @@ -131,7 +137,7 @@ void SAL_CALL OOXMLSecParser::endElement(const OUString& rName) throw (xml::sax: } m_pXSecController->setDigestValue(m_aDigestValue); } - else if (rName == "DigestValue") + else if (rName == "DigestValue" && !m_bInCertDigest) m_bInDigestValue = false; else if (rName == "SignatureValue") { @@ -163,6 +169,11 @@ void SAL_CALL OOXMLSecParser::endElement(const OUString& rName) throw (xml::sax: m_pXSecController->setX509SerialNumber(m_aX509SerialNumber); m_bInX509SerialNumber = false; } + else if (rName == "xd:CertDigest") + { + m_pXSecController->setCertDigest(m_aCertDigest); + m_bInCertDigest = false; + } if (m_xNextHandler.is()) m_xNextHandler->endElement(rName); @@ -170,7 +181,7 @@ void SAL_CALL OOXMLSecParser::endElement(const OUString& rName) throw (xml::sax: void SAL_CALL OOXMLSecParser::characters(const OUString& rChars) throw (xml::sax::SAXException, uno::RuntimeException, std::exception) { - if (m_bInDigestValue) + if (m_bInDigestValue && !m_bInCertDigest) m_aDigestValue += rChars; else if (m_bInSignatureValue) m_aSignatureValue += rChars; @@ -184,6 +195,8 @@ void SAL_CALL OOXMLSecParser::characters(const OUString& rChars) throw (xml::sax m_aX509IssuerName += rChars; else if (m_bInX509SerialNumber) m_aX509SerialNumber += rChars; + else if (m_bInCertDigest) + m_aCertDigest += rChars; if (m_xNextHandler.is()) m_xNextHandler->characters(rChars); diff --git a/xmlsecurity/source/helper/ooxmlsecparser.hxx b/xmlsecurity/source/helper/ooxmlsecparser.hxx index 819947b..cd3eed0 100644 --- a/xmlsecurity/source/helper/ooxmlsecparser.hxx +++ b/xmlsecurity/source/helper/ooxmlsecparser.hxx @@ -43,6 +43,8 @@ class OOXMLSecParser: public cppu::WeakImplHelper OUString m_aX509IssuerName; bool m_bInX509SerialNumber; OUString m_aX509SerialNumber; + bool m_bInCertDigest; + OUString m_aCertDigest; /// Last seen <Reference URI="...">. OUString m_aReferenceURI; diff --git a/xmlsecurity/source/helper/xsecctl.hxx b/xmlsecurity/source/helper/xsecctl.hxx index 38b70dc..9081b33 100644 --- a/xmlsecurity/source/helper/xsecctl.hxx +++ b/xmlsecurity/source/helper/xsecctl.hxx @@ -389,6 +389,7 @@ private: void setDate( OUString& ouDate ); void setDescription(const OUString& rDescription); + void setCertDigest(const OUString& rCertDigest); void setId( OUString& ouId ); void setPropertyId( OUString& ouPropertyId ); diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx index 856fdf7..a7e2183 100644 --- a/xmlsecurity/source/helper/xsecverify.cxx +++ b/xmlsecurity/source/helper/xsecverify.cxx @@ -274,6 +274,15 @@ void XSecController::setDescription(const OUString& rDescription) rInformation.signatureInfor.ouDescription = rDescription; } +void XSecController::setCertDigest(const OUString& rCertDigest) +{ + if (m_vInternalSignatureInformations.empty()) + return; + + InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back(); + rInformation.signatureInfor.ouCertDigest = rCertDigest; +} + void XSecController::setId( OUString& ouId ) { if (m_vInternalSignatureInformations.empty()) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits