diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/xmlsecurity-replace-XSecParser-implementation.diff | 2170 |
1 files changed, 2170 insertions, 0 deletions
diff --git a/debian/patches/xmlsecurity-replace-XSecParser-implementation.diff b/debian/patches/xmlsecurity-replace-XSecParser-implementation.diff new file mode 100644 index 000000000..861c4e226 --- /dev/null +++ b/debian/patches/xmlsecurity-replace-XSecParser-implementation.diff @@ -0,0 +1,2170 @@ +From ad5930e87e788780a255523f106deb1dde5d7b37 Mon Sep 17 00:00:00 2001 +From: Michael Stahl <michael.stahl@allotropia.de> +Date: Fri, 12 Feb 2021 16:42:51 +0100 +Subject: xmlsecurity: replace XSecParser implementation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement Namespaces in XML and follow xmldsig-core and XAdES schemas. + +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110833 +Tested-by: Jenkins +Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> +(cherry picked from commit 12b15be8f4f930a04d8056b9219ac969b42a9784) + +xmlsecurity: move XSecParser state into contexts + +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111158 +Tested-by: Jenkins +Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> +(cherry picked from commit 59df9e70ce1a7ec797b836bda7f9642912febc53) + +xmlsecurity: move XSecParser Reference state into contexts + +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111159 +Tested-by: Jenkins +Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> +(cherry picked from commit cfeb89a758b5f0ec406f0d72444e52ed2f47b85e) + +Change-Id: I03537b51bb757ecbfa63a826b38de543c70ba032 +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111907 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara <caolanm@redhat.com> +--- + include/xmloff/xmlimp.hxx | 6 +- + include/xmloff/xmlnmspe.hxx | 7 + + include/xmloff/xmltoken.hxx | 13 + + xmloff/source/core/xmlimp.cxx | 26 +- + xmloff/source/core/xmltoken.cxx | 13 + + xmloff/source/token/tokens.txt | 10 + + xmlsecurity/source/helper/xsecparser.cxx | 1634 ++++++++++++++++++++++++------ + xmlsecurity/source/helper/xsecparser.hxx | 99 +- + 8 files changed, 1427 insertions(+), 381 deletions(-) + +diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx +index 7f08609189ab..86871b7df445 100644 +--- a/include/xmloff/xmlimp.hxx ++++ b/include/xmloff/xmlimp.hxx +@@ -240,8 +240,12 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public cppu::WeakImplHelper< + + static void initializeNamespaceMaps(); + void registerNamespaces(); +- std::unique_ptr<SvXMLNamespaceMap> processNSAttributes( ++public: ++ static std::unique_ptr<SvXMLNamespaceMap> processNSAttributes( ++ std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap, ++ SvXMLImport *const pImport, + const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList); ++private: + void Characters(const OUString& aChars); + + css::uno::Reference< css::task::XStatusIndicator > mxStatusIndicator; +diff --git a/include/xmloff/xmlnmspe.hxx b/include/xmloff/xmlnmspe.hxx +index d45832f02d81..cabdcc7578e2 100644 +--- a/include/xmloff/xmlnmspe.hxx ++++ b/include/xmloff/xmlnmspe.hxx +@@ -69,6 +69,13 @@ constexpr sal_uInt16 XML_NAMESPACE_TCD = 34; // text conversion di + constexpr sal_uInt16 XML_NAMESPACE_DLG = 35; + constexpr sal_uInt16 XML_NAMESPACE_REPORT = 36; + constexpr sal_uInt16 XML_NAMESPACE_VERSIONS_LIST = 37; ++// OOo extension digital signatures, used in ODF 1.1 ++constexpr sal_uInt16 XML_NAMESPACE_DSIG_OOO = 38; ++// ODF 1.2 digital signature namespaces ++constexpr sal_uInt16 XML_NAMESPACE_DSIG = 39; ++constexpr sal_uInt16 XML_NAMESPACE_DS = 40; ++constexpr sal_uInt16 XML_NAMESPACE_XADES132 = 41; ++constexpr sal_uInt16 XML_NAMESPACE_XADES141 = 42; + + // namespaces for ODF extended formats + constexpr sal_uInt16 XML_NAMESPACE_EXT_BASE = 50; +diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx +index 49178ebdc996..b6956245ed17 100644 +--- a/include/xmloff/xmltoken.hxx ++++ b/include/xmloff/xmltoken.hxx +@@ -135,6 +135,19 @@ namespace xmloff::token { + XML_NP_GRDDL, + XML_N_GRDDL, + ++ // OOo extension digital signatures, used in ODF 1.1 ++ XML_NP_DSIG_OOO, ++ XML_N_DSIG_OOO, ++ // ODF 1.2 digital signatures ++ XML_NP_DSIG, ++ XML_N_DSIG, ++ XML_NP_DS, ++ XML_N_DS, ++ XML_NP_XADES132, ++ XML_N_XADES132, ++ XML_NP_XADES141, ++ XML_N_XADES141, ++ + // ODF Enhanced namespaces + XML_NP_OFFICE_EXT, + XML_N_OFFICE_EXT, +diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx +index 0c9e9d06cfd4..18429cc4860f 100644 +--- a/xmloff/source/core/xmlimp.cxx ++++ b/xmloff/source/core/xmlimp.cxx +@@ -665,6 +665,8 @@ void SAL_CALL SvXMLImport::endDocument() + } + + std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes( ++ std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap, ++ SvXMLImport *const pImport, // TODO??? + const uno::Reference< xml::sax::XAttributeList >& xAttrList) + { + std::unique_ptr<SvXMLNamespaceMap> pRewindMap; +@@ -672,12 +674,13 @@ std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes( + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + const OUString& rAttrName = xAttrList->getNameByIndex( i ); +- if ( rAttrName == "office:version" ) ++ if (pImport && rAttrName == "office:version") + { +- mpImpl->aODFVersion = xAttrList->getValueByIndex( i ); ++ pImport->mpImpl->aODFVersion = xAttrList->getValueByIndex( i ); + + // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2 +- if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( mpImpl->aODFVersion ) ) ++ if (pImport->mpImpl->mStreamName == "content.xml" ++ && !pImport->IsODFVersionConsistent(pImport->mpImpl->aODFVersion)) + { + throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!", + uno::Reference< uno::XInterface >(), +@@ -691,8 +694,8 @@ std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes( + { + if( !pRewindMap ) + { +- pRewindMap = std::move(mpNamespaceMap); +- mpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap)); ++ pRewindMap = std::move(rpNamespaceMap); ++ rpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap)); + } + const OUString& rAttrValue = xAttrList->getValueByIndex( i ); + +@@ -700,18 +703,18 @@ std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes( + ? OUString() + : rAttrName.copy( 6 ) ); + // Add namespace, but only if it is known. +- sal_uInt16 nKey = mpNamespaceMap->AddIfKnown( aPrefix, rAttrValue ); ++ sal_uInt16 nKey = rpNamespaceMap->AddIfKnown( aPrefix, rAttrValue ); + // If namespace is unknown, try to match a name with similar + // TC Id and version + if( XML_NAMESPACE_UNKNOWN == nKey ) + { + OUString aTestName( rAttrValue ); + if( SvXMLNamespaceMap::NormalizeURI( aTestName ) ) +- nKey = mpNamespaceMap->AddIfKnown( aPrefix, aTestName ); ++ nKey = rpNamespaceMap->AddIfKnown( aPrefix, aTestName ); + } + // If that namespace is not known, too, add it as unknown + if( XML_NAMESPACE_UNKNOWN == nKey ) +- mpNamespaceMap->Add( aPrefix, rAttrValue ); ++ rpNamespaceMap->Add( aPrefix, rAttrValue ); + + } + } +@@ -724,7 +727,8 @@ void SAL_CALL SvXMLImport::startElement( const OUString& rName, + // SAL_INFO("svg", "startElement " << rName); + // Process namespace attributes. This must happen before creating the + // context, because namespace declaration apply to the element name itself. +- std::unique_ptr<SvXMLNamespaceMap> pRewindMap(processNSAttributes(xAttrList)); ++ std::unique_ptr<SvXMLNamespaceMap> pRewindMap( ++ processNSAttributes(mpNamespaceMap, this, xAttrList)); + + // Get element's namespace and local name. + OUString aLocalName; +@@ -898,7 +902,7 @@ void SAL_CALL SvXMLImport::startFastElement (sal_Int32 Element, + + maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList ); + std::unique_ptr<SvXMLNamespaceMap> pRewindMap( +- processNSAttributes( maNamespaceAttrList.get() )); ++ processNSAttributes(mpNamespaceMap, this, maNamespaceAttrList.get())); + assert( dynamic_cast<SvXMLImportContext*>( xContext.get() ) != nullptr ); + SvXMLImportContext *pContext = static_cast<SvXMLImportContext*>( xContext.get() ); + if (pRewindMap) +@@ -2251,7 +2255,7 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument() + void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) + { +- mrImport->processNSAttributes(xAttrList); ++ SvXMLImport::processNSAttributes(mrImport->mpNamespaceMap, mrImport.get(), xAttrList); + OUString aLocalName; + sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName ); + Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>( +diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx +index 8d9a70f5e082..91c014f5756f 100644 +--- a/xmloff/source/core/xmltoken.cxx ++++ b/xmloff/source/core/xmltoken.cxx +@@ -144,6 +144,19 @@ namespace xmloff::token { + TOKEN( "grddl", XML_NP_GRDDL ), + TOKEN( "http://www.w3.org/2003/g/data-view#", XML_N_GRDDL ), + ++ // OOo extension digital signatures, used in ODF 1.1 ++ TOKEN( "dsigooo", XML_NP_DSIG_OOO ), ++ TOKEN( "http://openoffice.org/2004/documentsignatures", XML_N_DSIG_OOO ), ++ // ODF 1.2 digital signature namespaces ++ TOKEN( "dsig", XML_NP_DSIG ), ++ TOKEN( "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0", XML_N_DSIG ), ++ TOKEN( "ds", XML_NP_DS ), ++ TOKEN( "http://www.w3.org/2000/09/xmldsig#", XML_N_DS ), ++ TOKEN( "xades132", XML_NP_XADES132 ), ++ TOKEN( "http://uri.etsi.org/01903/v1.3.2#", XML_N_XADES132 ), ++ TOKEN( "xades141", XML_NP_XADES141 ), ++ TOKEN( "http://uri.etsi.org/01903/v1.4.1#", XML_N_XADES141 ), ++ + // ODF Enhanced namespaces + TOKEN( "officeooo", XML_NP_OFFICE_EXT ), + TOKEN( "http://openoffice.org/2009/office", XML_N_OFFICE_EXT ), +diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt +index 34b9af91e03c..495e519ffb2d 100644 +--- a/xmloff/source/token/tokens.txt ++++ b/xmloff/source/token/tokens.txt +@@ -72,6 +72,16 @@ xhtml + N_XHTML_DUMMY + grddl + N_GRDDL_DUMMY ++dsigooo ++N_DSIG_OOO_DUMMY ++dsig ++N_DSIG_DUMMY ++ds ++N_DS_DUMMY ++xades132 ++N_XADES132_DUMMY ++xades141 ++N_XADES141_DUMMY + officeooo + N_OFFICE_EXT_DUMMY + formx +diff --git a/xmlsecurity/source/helper/xsecparser.cxx b/xmlsecurity/source/helper/xsecparser.cxx +index 9f2bbe074a1b..0aecb1854f8c 100644 +--- a/xmlsecurity/source/helper/xsecparser.cxx ++++ b/xmlsecurity/source/helper/xsecparser.cxx +@@ -21,476 +21,1468 @@ + #include "xsecparser.hxx" + #include <xsecctl.hxx> + #include <xmlsignaturehelper.hxx> ++ ++#include <xmloff/xmlnmspe.hxx> ++#include <xmloff/xmlimp.hxx> ++ + #include <com/sun/star/xml/sax/SAXException.hpp> + #include <cppuhelper/exc_hlp.hxx> + #include <sal/log.hxx> + ++class XSecParser::Context ++{ ++ protected: ++ friend class XSecParser; ++ XSecParser & m_rParser; ++ private: ++ std::unique_ptr<SvXMLNamespaceMap> m_pOldNamespaceMap; + +-XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper, +- XSecController* pXSecController) +- : m_bInX509IssuerName(false) +- , m_bInX509SerialNumber(false) +- , m_bInX509Certificate(false) +- , m_bInGpgCertificate(false) +- , m_bInGpgKeyID(false) +- , m_bInGpgOwner(false) +- , m_bInCertDigest(false) +- , m_bInEncapsulatedX509Certificate(false) +- , m_bInSigningTime(false) +- , m_bInDigestValue(false) +- , m_bInSignatureValue(false) +- , m_bInDate(false) +- , m_bInDescription(false) +- , m_bInSignatureLineId(false) +- , m_bInSignatureLineValidImage(false) +- , m_bInSignatureLineInvalidImage(false) +- , m_pXSecController(pXSecController) +- , m_bReferenceUnresolved(false) +- , m_nReferenceDigestID(css::xml::crypto::DigestID::SHA1) +- , m_rXMLSignatureHelper(rXMLSignatureHelper) ++ public: ++ Context(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : m_rParser(rParser) ++ , m_pOldNamespaceMap(std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual ~Context() = default; ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) ++ { ++ } ++ ++ virtual void EndElement() ++ { ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/); ++ ++ virtual void Characters(OUString const& /*rChars*/) ++ { ++ } ++}; ++ ++// it's possible that an unsupported element has an Id attribute and a ++// ds:Reference digesting it - probably this means XSecController needs to know ++// about it. (For known elements, the Id attribute is only processed according ++// to the schema.) ++class XSecParser::UnknownContext ++ : public XSecParser::Context + { ++ public: ++ UnknownContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++}; ++ ++auto XSecParser::Context::CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/) ++-> std::unique_ptr<Context> ++{ ++ // default: create new base context ++ return std::make_unique<UnknownContext>(m_rParser, std::move(pOldNamespaceMap)); + } + +-OUString XSecParser::getIdAttr(const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs ) ++class XSecParser::LoPGPOwnerContext ++ : public XSecParser::Context + { +- OUString ouIdAttr = xAttribs->getValueByName("id"); ++ private: ++ OUString m_Value; + +- if (ouIdAttr.isEmpty()) +- { +- ouIdAttr = xAttribs->getValueByName("Id"); +- } ++ public: ++ LoPGPOwnerContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } + +- return ouIdAttr; +-} ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setGpgOwner(m_Value); ++ } + +-/* +- * XDocumentHandler +- */ +-void SAL_CALL XSecParser::startDocument( ) ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::DsPGPKeyPacketContext ++ : public XSecParser::Context + { +- m_bInX509IssuerName = false; +- m_bInX509SerialNumber = false; +- m_bInX509Certificate = false; +- m_bInGpgCertificate = false; +- m_bInGpgKeyID = false; +- m_bInGpgOwner = false; +- m_bInSignatureValue = false; +- m_bInDigestValue = false; +- m_bInDate = false; +- m_bInDescription = false; ++ private: ++ OUString m_Value; + +- if (m_xNextHandler.is()) +- { +- m_xNextHandler->startDocument(); +- } +-} ++ public: ++ DsPGPKeyPacketContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } + +-void SAL_CALL XSecParser::endDocument( ) ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setGpgCertificate(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::DsPGPKeyIDContext ++ : public XSecParser::Context + { +- if (m_xNextHandler.is()) +- { +- m_xNextHandler->endDocument(); +- } +-} ++ private: ++ OUString m_Value; + +-void SAL_CALL XSecParser::startElement( +- const OUString& aName, +- const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs ) ++ public: ++ DsPGPKeyIDContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setGpgKeyID(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::DsPGPDataContext ++ : public XSecParser::Context + { +- try +- { +- OUString ouIdAttr = getIdAttr(xAttribs); +- if (!ouIdAttr.isEmpty()) ++ public: ++ DsPGPDataContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override ++ { ++ m_rParser.m_pXSecController->switchGpgSignature(); ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_DS && rName == "PGPKeyID") ++ { ++ return std::make_unique<DsPGPKeyIDContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "PGPKeyPacket") ++ { ++ return std::make_unique<DsPGPKeyPacketContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "PGPOwner") ++ { ++ return std::make_unique<LoPGPOwnerContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::DsX509CertificateContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ DsX509CertificateContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setX509Certificate(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::DsX509SerialNumberContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ DsX509SerialNumberContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setX509SerialNumber(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::DsX509IssuerNameContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ DsX509IssuerNameContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setX509IssuerName(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::DsX509IssuerSerialContext ++ : public XSecParser::Context ++{ ++ public: ++ DsX509IssuerSerialContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerName") ++ { ++ return std::make_unique<DsX509IssuerNameContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "X509SerialNumber") ++ { ++ return std::make_unique<DsX509SerialNumberContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::DsX509DataContext ++ : public XSecParser::Context ++{ ++ public: ++ DsX509DataContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerSerial") ++ { ++ return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "X509Certificate") ++ { ++ return std::make_unique<DsX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::DsKeyInfoContext ++ : public XSecParser::Context ++{ ++ public: ++ DsKeyInfoContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_DS && rName == "X509Data") ++ { ++ return std::make_unique<DsX509DataContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "PGPData") ++ { ++ return std::make_unique<DsPGPDataContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: ds:KeyName, ds:KeyValue, ds:RetrievalMethod, ds:SPKIData, ds:MgmtData ++ // (old code would read ds:Transform inside ds:RetrievalMethod but ++ // presumably that was a bug) ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++ ++}; ++ ++class XSecParser::DsSignatureValueContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ DsSignatureValueContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setSignatureValue(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::DsDigestValueContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString & m_rValue; ++ ++ public: ++ DsDigestValueContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ OUString & rValue) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ , m_rValue(rValue) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override ++ { ++ m_rValue.clear(); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_rValue += rChars; ++ } ++}; ++ ++class XSecParser::DsDigestMethodContext ++ : public XSecParser::Context ++{ ++ private: ++ sal_Int32 & m_rReferenceDigestID; ++ ++ public: ++ DsDigestMethodContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_Int32 & rReferenceDigestID) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ , m_rReferenceDigestID(rReferenceDigestID) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm"); ++ ++ SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" ); ++ if (!ouAlgorithm.isEmpty()) ++ { ++ SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1 ++ && ouAlgorithm != ALGO_XMLDSIGSHA256 ++ && ouAlgorithm != ALGO_XMLDSIGSHA512, ++ "xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512"); ++ if (ouAlgorithm == ALGO_XMLDSIGSHA1) ++ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA1; ++ else if (ouAlgorithm == ALGO_XMLDSIGSHA256) ++ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA256; ++ else if (ouAlgorithm == ALGO_XMLDSIGSHA512) ++ m_rReferenceDigestID = css::xml::crypto::DigestID::SHA512; ++ else ++ m_rReferenceDigestID = 0; ++ } ++ } ++}; ++ ++class XSecParser::DsTransformContext ++ : public XSecParser::Context ++{ ++ private: ++ bool & m_rIsC14N; ++ ++ public: ++ DsTransformContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ bool & rIsC14N) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ , m_rIsC14N(rIsC14N) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm"); ++ ++ if (ouAlgorithm == ALGO_C14N) ++ /* ++ * a xml stream ++ */ ++ { ++ m_rIsC14N = true; ++ } ++ } ++}; ++ ++class XSecParser::DsTransformsContext ++ : public XSecParser::Context ++{ ++ private: ++ bool & m_rIsC14N; ++ ++ public: ++ DsTransformsContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ bool & rIsC14N) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ , m_rIsC14N(rIsC14N) ++ { ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_DS && rName == "Transform") ++ { ++ return std::make_unique<DsTransformContext>(m_rParser, std::move(pOldNamespaceMap), m_rIsC14N); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::DsReferenceContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_URI; ++ OUString m_Type; ++ OUString m_DigestValue; ++ bool m_IsC14N = false; ++ // Relevant for ODF. The digest algorithm selected by the DigestMethod ++ // element's Algorithm attribute. @see css::xml::crypto::DigestID. ++ sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1; ++ ++ public: ++ DsReferenceContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ ++ m_URI = xAttrs->getValueByName("URI"); ++ SAL_WARN_IF(m_URI.isEmpty(), "xmlsecurity.helper", "URI is empty"); ++ // Remember the type of this reference. ++ m_Type = xAttrs->getValueByName("Type"); ++ } ++ ++ virtual void EndElement() override ++ { ++ if (m_URI.startsWith("#")) ++ { ++ /* ++ * remove the first character '#' from the attribute value ++ */ ++ m_rParser.m_pXSecController->addReference(m_URI.copy(1), m_nReferenceDigestID, m_Type); ++ } ++ else ++ { ++ if (m_IsC14N) // this is determined by nested ds:Transform ++ { ++ m_rParser.m_pXSecController->addStreamReference(m_URI, false, m_nReferenceDigestID); ++ } ++ else ++ /* ++ * it must be an octet stream ++ */ ++ { ++ m_rParser.m_pXSecController->addStreamReference(m_URI, true, m_nReferenceDigestID); ++ } ++ } ++ ++ m_rParser.m_pXSecController->setDigestValue(m_nReferenceDigestID, m_DigestValue); ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_DS && rName == "Transforms") ++ { ++ return std::make_unique<DsTransformsContext>(m_rParser, std::move(pOldNamespaceMap), m_IsC14N); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod") ++ { ++ return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_nReferenceDigestID); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue") ++ { ++ return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_DigestValue); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::DsSignatureMethodContext ++ : public XSecParser::Context ++{ ++ public: ++ DsSignatureMethodContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ OUString ouAlgorithm = xAttrs->getValueByName("Algorithm"); ++ if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256 ++ || ouAlgorithm == ALGO_ECDSASHA512) ++ { ++ m_rParser.m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA); ++ } ++ } ++}; ++ ++class XSecParser::DsSignedInfoContext ++ : public XSecParser::Context ++{ ++ public: ++ DsSignedInfoContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setReferenceCount(); ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureMethod") ++ { ++ return std::make_unique<DsSignatureMethodContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "Reference") ++ { ++ return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: ds:CanonicalizationMethod ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::XadesEncapsulatedX509CertificateContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ XadesEncapsulatedX509CertificateContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->addEncapsulatedX509Certificate(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::XadesCertificateValuesContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesCertificateValuesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "EncapsulatedX509Certificate") ++ { ++ return std::make_unique<XadesEncapsulatedX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: xades:OtherCertificate ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::XadesUnsignedSignaturePropertiesContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesUnsignedSignaturePropertiesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertificateValues") ++ { ++ return std::make_unique<XadesCertificateValuesContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: ++ // xades:CounterSignature ++ // ^ old code would read a ds:Signature inside it? ++ // xades:SignatureTimeStamp ++ // xades:CompleteCertificateRefs ++ // xades:CompleteRevocationRefs ++ // xades:AttributeCertificateRefs ++ // xades:AttributeRevocationRefs ++ // xades:SigAndRefsTimeStamp ++ // xades:RefsOnlyTimeStamp ++ // xades:RevocationValues ++ // xades:AttrAuthoritiesCertValues ++ // ^ old code: was equivalent to CertificateValues ??? ++ // xades:AttributeRevocationValues ++ // xades:ArchiveTimeStamp ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::XadesUnsignedPropertiesContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesUnsignedPropertiesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override ++ { ++ m_rParser.HandleIdAttr(xAttrs); ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "UnsignedSignatureProperties") ++ { ++ return std::make_unique<XadesUnsignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: xades:UnsignedDataObjectProperties ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); ++ } ++}; ++ ++class XSecParser::LoSignatureLineIdContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ LoSignatureLineIdContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setSignatureLineId(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::LoSignatureLineValidImageContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ LoSignatureLineValidImageContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setValidSignatureImage(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override + { +- m_pXSecController->collectToVerify( ouIdAttr ); ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::LoSignatureLineInvalidImageContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ LoSignatureLineInvalidImageContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual void EndElement() override ++ { ++ m_rParser.m_pXSecController->setInvalidSignatureImage(m_Value); ++ } ++ ++ virtual void Characters(OUString const& rChars) override ++ { ++ m_Value += rChars; ++ } ++}; ++ ++class XSecParser::LoSignatureLineContext ++ : public XSecParser::Context ++{ ++ public: ++ LoSignatureLineContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) ++ { ++ } ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLineId") ++ { ++ return std::make_unique<LoSignatureLineIdContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLineValidImage") ++ { ++ return std::make_unique<LoSignatureLineValidImageContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLineInvalidImage") ++ { ++ return std::make_unique<LoSignatureLineInvalidImageContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } ++}; + +- if ( aName == "Signature" ) ++class XSecParser::XadesCertDigestContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1; ++ ++ public: ++ XadesCertDigestContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_rXMLSignatureHelper.StartVerifySignatureElement(); +- m_pXSecController->addSignature(); +- if (!ouIdAttr.isEmpty()) +- { +- m_pXSecController->setId( ouIdAttr ); +- } + } +- else if (aName == "SignatureMethod") ++ ++ virtual void EndElement() override + { +- OUString ouAlgorithm = xAttribs->getValueByName("Algorithm"); +- if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256 +- || ouAlgorithm == ALGO_ECDSASHA512) +- m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA); ++ m_rParser.m_pXSecController->setCertDigest(m_Value/* FIXME , m_nReferenceDigestID*/); + } +- else if ( aName == "Reference" ) ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- OUString ouUri = xAttribs->getValueByName("URI"); +- SAL_WARN_IF( ouUri.isEmpty(), "xmlsecurity.helper", "URI is empty" ); +- // Remember the type of this reference. +- OUString ouType = xAttribs->getValueByName("Type"); +- if (ouUri.startsWith("#")) ++ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod") + { +- /* +- * remove the first character '#' from the attribute value +- */ +- m_pXSecController->addReference( ouUri.copy(1), m_nReferenceDigestID, ouType ); ++ return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_nReferenceDigestID); + } +- else ++ if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue") + { +- /* +- * remember the uri +- */ +- m_currentReferenceURI = ouUri; +- m_bReferenceUnresolved = true; ++ return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_Value); + } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "DigestMethod") ++}; ++ ++class XSecParser::XadesCertContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesCertContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- OUString ouAlgorithm = xAttribs->getValueByName("Algorithm"); ++ } + +- SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" ); +- if (!ouAlgorithm.isEmpty()) ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override ++ { ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertDigest") + { +- SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1 +- && ouAlgorithm != ALGO_XMLDSIGSHA256 +- && ouAlgorithm != ALGO_XMLDSIGSHA512, +- "xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512"); +- if (ouAlgorithm == ALGO_XMLDSIGSHA1) +- m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1; +- else if (ouAlgorithm == ALGO_XMLDSIGSHA256) +- m_nReferenceDigestID = css::xml::crypto::DigestID::SHA256; +- else if (ouAlgorithm == ALGO_XMLDSIGSHA512) +- m_nReferenceDigestID = css::xml::crypto::DigestID::SHA512; +- else +- m_nReferenceDigestID = 0; ++ return std::make_unique<XadesCertDigestContext>(m_rParser, std::move(pOldNamespaceMap)); + } +- } +- else if (aName == "Transform") +- { +- if ( m_bReferenceUnresolved ) ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "IssuerSerial") + { +- OUString ouAlgorithm = xAttribs->getValueByName("Algorithm"); +- +- if (ouAlgorithm == ALGO_C14N) +- /* +- * a xml stream +- */ +- { +- m_pXSecController->addStreamReference( m_currentReferenceURI, false, m_nReferenceDigestID ); +- m_bReferenceUnresolved = false; +- } ++ return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap)); + } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "X509IssuerName") +- { +- m_ouX509IssuerName.clear(); +- m_bInX509IssuerName = true; +- } +- else if (aName == "X509SerialNumber") ++}; ++ ++class XSecParser::XadesSigningCertificateContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesSigningCertificateContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_ouX509SerialNumber.clear(); +- m_bInX509SerialNumber = true; + } +- else if (aName == "X509Certificate") ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- m_ouX509Certificate.clear(); +- m_bInX509Certificate = true; ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "Cert") ++ { ++ return std::make_unique<XadesCertContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "PGPData") ++}; ++ ++class XSecParser::XadesSigningTimeContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesSigningTimeContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_pXSecController->switchGpgSignature(); + } +- else if (aName == "PGPKeyID") ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override + { +- m_ouGpgKeyID.clear(); +- m_bInGpgKeyID = true; ++ m_rParser.m_ouDate.clear(); + } +- else if (aName == "PGPKeyPacket") ++ ++ virtual void EndElement() override + { +- m_ouGpgCertificate.clear(); +- m_bInGpgCertificate = true; ++ m_rParser.m_pXSecController->setDate( m_rParser.m_ouDate ); + } +- else if (aName == "loext:PGPOwner") ++ ++ virtual void Characters(OUString const& rChars) override + { +- m_ouGpgOwner.clear(); +- m_bInGpgOwner = true; ++ m_rParser.m_ouDate += rChars; + } +- else if (aName == "SignatureValue") ++}; ++ ++class XSecParser::XadesSignedSignaturePropertiesContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesSignedSignaturePropertiesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_ouSignatureValue.clear(); +- m_bInSignatureValue = true; + } +- else if (aName == "DigestValue" && !m_bInCertDigest) ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { +- m_ouDigestValue.clear(); +- m_bInDigestValue = true; ++ m_rParser.HandleIdAttr(xAttrs); + } +- else if (aName == "xd:CertDigest") ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- m_ouCertDigest.clear(); +- m_bInCertDigest = true; ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningTime") ++ { ++ return std::make_unique<XadesSigningTimeContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningCertificate") ++ { ++ return std::make_unique<XadesSigningCertificateContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLine") ++ { ++ return std::make_unique<LoSignatureLineContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ // missing: xades:SignaturePolicyIdentifier, xades:SignatureProductionPlace, xades:SignerRole ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- // FIXME: Existing code here in xmlsecurity uses "xd" as the namespace prefix for XAdES, +- // while the sample document attached to tdf#76142 uses "xades". So accept either here. Of +- // course this is idiotic and wrong, the right thing would be to use a proper way to parse +- // XML that would handle namespaces correctly. I have no idea how substantial re-plumbing of +- // this code that would require. +- else if (aName == "xd:EncapsulatedX509Certificate" || aName == "xades:EncapsulatedX509Certificate") ++}; ++ ++class XSecParser::XadesSignedPropertiesContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesSignedPropertiesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_ouEncapsulatedX509Certificate.clear(); +- m_bInEncapsulatedX509Certificate = true; + } +- else if (aName == "xd:SigningTime" || aName == "xades:SigningTime") ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { +- m_ouDate.clear(); +- m_bInSigningTime = true; ++ m_rParser.HandleIdAttr(xAttrs); + } +- else if ( aName == "SignatureProperty" ) ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- if (!ouIdAttr.isEmpty()) ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedSignatureProperties") + { +- m_pXSecController->setPropertyId( ouIdAttr ); ++ return std::make_unique<XadesSignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); + } ++ // missing: xades:SignedDataObjectProperties ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "dc:date") +- { +- if (m_ouDate.isEmpty()) +- m_bInDate = true; +- } +- else if (aName == "dc:description") ++}; ++ ++class XSecParser::XadesQualifyingPropertiesContext ++ : public XSecParser::Context ++{ ++ public: ++ XadesQualifyingPropertiesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_ouDescription.clear(); +- m_bInDescription = true; + } +- else if (aName == "loext:SignatureLineId") ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { +- m_ouSignatureLineId.clear(); +- m_bInSignatureLineId = true; ++ m_rParser.HandleIdAttr(xAttrs); + } +- else if (aName == "loext:SignatureLineValidImage") ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- m_ouSignatureLineValidImage.clear(); +- m_bInSignatureLineValidImage = true; ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedProperties") ++ { ++ return std::make_unique<XadesSignedPropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "UnsignedProperties") ++ { ++ return std::make_unique<XadesUnsignedPropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "loext:SignatureLineInvalidImage") ++}; ++ ++class XSecParser::DcDateContext ++ : public XSecParser::Context ++{ ++ private: ++ bool m_isIgnore = false; ++ ++ public: ++ DcDateContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_ouSignatureLineInvalidImage.clear(); +- m_bInSignatureLineInvalidImage = true; + } + +- if (m_xNextHandler.is()) ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override + { +- m_xNextHandler->startElement(aName, xAttribs); ++ m_isIgnore = !m_rParser.m_ouDate.isEmpty(); + } +- } +- catch (css::uno::Exception& ) +- {//getCaughtException MUST be the first line in the catch block +- css::uno::Any exc = cppu::getCaughtException(); +- throw css::xml::sax::SAXException( +- "xmlsecurity: Exception in XSecParser::startElement", +- nullptr, exc); +- } +- catch (...) +- { +- throw css::xml::sax::SAXException( +- "xmlsecurity: unexpected exception in XSecParser::startElement", nullptr, +- css::uno::Any()); +- } +-} + +-void SAL_CALL XSecParser::endElement( const OUString& aName ) +-{ +- try +- { +- if (aName == "DigestValue" && !m_bInCertDigest) ++ virtual void EndElement() override + { +- m_bInDigestValue = false; ++ if (!m_isIgnore) ++ { ++ m_rParser.m_pXSecController->setDate( m_rParser.m_ouDate ); ++ } + } +- else if ( aName == "Reference" ) ++ ++ virtual void Characters(OUString const& rChars) override + { +- if ( m_bReferenceUnresolved ) +- /* +- * it must be an octet stream +- */ ++ if (!m_isIgnore) + { +- m_pXSecController->addStreamReference( m_currentReferenceURI, true, m_nReferenceDigestID ); +- m_bReferenceUnresolved = false; ++ m_rParser.m_ouDate += rChars; + } +- +- m_pXSecController->setDigestValue( m_nReferenceDigestID, m_ouDigestValue ); + } +- else if ( aName == "SignedInfo" ) ++}; ++ ++class XSecParser::DcDescriptionContext ++ : public XSecParser::Context ++{ ++ private: ++ OUString m_Value; ++ ++ public: ++ DcDescriptionContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_pXSecController->setReferenceCount(); + } +- else if ( aName == "SignatureValue" ) ++ ++ virtual void EndElement() override + { +- m_pXSecController->setSignatureValue( m_ouSignatureValue ); +- m_bInSignatureValue = false; ++ m_rParser.m_pXSecController->setDescription(m_Value); + } +- else if (aName == "X509IssuerName") ++ ++ virtual void Characters(OUString const& rChars) override + { +- m_pXSecController->setX509IssuerName( m_ouX509IssuerName ); +- m_bInX509IssuerName = false; ++ m_Value += rChars; + } +- else if (aName == "X509SerialNumber") ++}; ++ ++class XSecParser::DsSignaturePropertyContext ++ : public XSecParser::Context ++{ ++ public: ++ DsSignaturePropertyContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_pXSecController->setX509SerialNumber( m_ouX509SerialNumber ); +- m_bInX509SerialNumber = false; + } +- else if (aName == "X509Certificate") ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { +- m_pXSecController->setX509Certificate( m_ouX509Certificate ); +- m_bInX509Certificate = false; ++ OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs)); ++ if (!ouIdAttr.isEmpty()) ++ { ++ m_rParser.m_pXSecController->setPropertyId( ouIdAttr ); ++ } + } +- else if (aName == "PGPKeyID") ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- m_pXSecController->setGpgKeyID( m_ouGpgKeyID ); +- m_bInGpgKeyID = false; ++ if (nNamespace == XML_NAMESPACE_DC && rName == "date") ++ { ++ return std::make_unique<DcDateContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DC && rName == "description") ++ { ++ return std::make_unique<DcDescriptionContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "PGPKeyPacket") ++}; ++ ++class XSecParser::DsSignaturePropertiesContext ++ : public XSecParser::Context ++{ ++ public: ++ DsSignaturePropertiesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_pXSecController->setGpgCertificate( m_ouGpgCertificate ); +- m_bInGpgCertificate = false; + } +- else if (aName == "loext:PGPOwner") ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { +- m_pXSecController->setGpgOwner( m_ouGpgOwner ); +- m_bInGpgOwner = false; ++ m_rParser.HandleIdAttr(xAttrs); + } +- else if (aName == "xd:CertDigest") ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- m_pXSecController->setCertDigest( m_ouCertDigest ); +- m_bInCertDigest = false; ++ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperty") ++ { ++ return std::make_unique<DsSignaturePropertyContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "xd:EncapsulatedX509Certificate" || aName == "xades:EncapsulatedX509Certificate") ++}; ++ ++class XSecParser::DsObjectContext ++ : public XSecParser::Context ++{ ++ public: ++ DsObjectContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_pXSecController->addEncapsulatedX509Certificate( m_ouEncapsulatedX509Certificate ); +- m_bInEncapsulatedX509Certificate = false; + } +- else if (aName == "xd:SigningTime" || aName == "xades:SigningTime") ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { +- m_pXSecController->setDate( m_ouDate ); +- m_bInSigningTime = false; ++ m_rParser.HandleIdAttr(xAttrs); + } +- else if (aName == "dc:date") ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- if (m_bInDate) ++ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperties") ++ { ++ return std::make_unique<DsSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_XADES132 && rName == "QualifyingProperties") + { +- m_pXSecController->setDate( m_ouDate ); +- m_bInDate = false; ++ return std::make_unique<XadesQualifyingPropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); + } ++ // missing: ds:Manifest ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "dc:description") ++}; ++ ++class XSecParser::DsSignatureContext ++ : public XSecParser::Context ++{ ++ public: ++ DsSignatureContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_pXSecController->setDescription( m_ouDescription ); +- m_bInDescription = false; + } +- else if (aName == "loext:SignatureLineId") ++ ++ virtual void StartElement( ++ css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { +- m_pXSecController->setSignatureLineId( m_ouSignatureLineId ); +- m_bInSignatureLineId = false; ++ OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs)); ++ m_rParser.m_rXMLSignatureHelper.StartVerifySignatureElement(); ++ m_rParser.m_pXSecController->addSignature(); ++ if (!ouIdAttr.isEmpty()) ++ { ++ m_rParser.m_pXSecController->setId( ouIdAttr ); ++ } + } +- else if (aName == "loext:SignatureLineValidImage") ++ ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- m_pXSecController->setValidSignatureImage( m_ouSignatureLineValidImage ); +- m_bInSignatureLineValidImage = false; ++ if (nNamespace == XML_NAMESPACE_DS && rName == "SignedInfo") ++ { ++ return std::make_unique<DsSignedInfoContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureValue") ++ { ++ return std::make_unique<DsSignatureValueContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "KeyInfo") ++ { ++ return std::make_unique<DsKeyInfoContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ if (nNamespace == XML_NAMESPACE_DS && rName == "Object") ++ { ++ return std::make_unique<DsObjectContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- else if (aName == "loext:SignatureLineInvalidImage") ++}; ++ ++class XSecParser::DsigSignaturesContext ++ : public XSecParser::Context ++{ ++ public: ++ DsigSignaturesContext(XSecParser & rParser, ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) ++ : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) + { +- m_pXSecController->setInvalidSignatureImage( m_ouSignatureLineInvalidImage ); +- m_bInSignatureLineInvalidImage = false; + } + +- if (m_xNextHandler.is()) ++ virtual std::unique_ptr<Context> CreateChildContext( ++ std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, ++ sal_uInt16 const nNamespace, OUString const& rName) override + { +- m_xNextHandler->endElement(aName); ++ if (nNamespace == XML_NAMESPACE_DS && rName == "Signature") ++ { ++ return std::make_unique<DsSignatureContext>(m_rParser, std::move(pOldNamespaceMap)); ++ } ++ return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +- } +- catch (css::uno::Exception& ) +- {//getCaughtException MUST be the first line in the catch block +- css::uno::Any exc = cppu::getCaughtException(); +- throw css::xml::sax::SAXException( +- "xmlsecurity: Exception in XSecParser::endElement", +- nullptr, exc); +- } +- catch (...) +- { +- throw css::xml::sax::SAXException( +- "xmlsecurity: unexpected exception in XSecParser::endElement", nullptr, +- css::uno::Any()); +- } ++}; ++ ++ ++XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper, ++ XSecController* pXSecController) ++ : m_pNamespaceMap(new SvXMLNamespaceMap) ++ , m_pXSecController(pXSecController) ++ , m_rXMLSignatureHelper(rXMLSignatureHelper) ++{ ++ using namespace xmloff::token; ++ m_pNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML ); ++ m_pNamespaceMap->Add( "_dsig_ooo", GetXMLToken(XML_N_DSIG_OOO), XML_NAMESPACE_DSIG_OOO ); ++ m_pNamespaceMap->Add( "_dsig", GetXMLToken(XML_N_DSIG), XML_NAMESPACE_DSIG ); ++ m_pNamespaceMap->Add( "_ds", GetXMLToken(XML_N_DS), XML_NAMESPACE_DS ); ++ m_pNamespaceMap->Add( "_xades132", GetXMLToken(XML_N_XADES132), XML_NAMESPACE_XADES132); ++ m_pNamespaceMap->Add( "_xades141", GetXMLToken(XML_N_XADES141), XML_NAMESPACE_XADES141); ++ m_pNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC ); ++ m_pNamespaceMap->Add( "_office_libo", ++ GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT); + } + +-void SAL_CALL XSecParser::characters( const OUString& aChars ) ++OUString XSecParser::HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) + { +- if (m_bInX509IssuerName) +- { +- m_ouX509IssuerName += aChars; +- } +- else if (m_bInX509SerialNumber) +- { +- m_ouX509SerialNumber += aChars; +- } +- else if (m_bInX509Certificate) +- { +- m_ouX509Certificate += aChars; +- } +- else if (m_bInGpgCertificate) ++ OUString ouIdAttr = getIdAttr(xAttrs); ++ if (!ouIdAttr.isEmpty()) + { +- m_ouGpgCertificate += aChars; ++ m_pXSecController->collectToVerify( ouIdAttr ); + } +- else if (m_bInGpgKeyID) ++ return ouIdAttr; ++} ++ ++OUString XSecParser::getIdAttr(const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs ) ++{ ++ OUString ouIdAttr = xAttribs->getValueByName("id"); ++ ++ if (ouIdAttr.isEmpty()) + { +- m_ouGpgKeyID += aChars; ++ ouIdAttr = xAttribs->getValueByName("Id"); + } +- else if (m_bInGpgOwner) ++ ++ return ouIdAttr; ++} ++ ++/* ++ * XDocumentHandler ++ */ ++void SAL_CALL XSecParser::startDocument( ) ++{ ++ if (m_xNextHandler.is()) + { +- m_ouGpgOwner += aChars; ++ m_xNextHandler->startDocument(); + } +- else if (m_bInSignatureValue) ++} ++ ++void SAL_CALL XSecParser::endDocument( ) ++{ ++ if (m_xNextHandler.is()) + { +- m_ouSignatureValue += aChars; ++ m_xNextHandler->endDocument(); + } +- else if (m_bInDigestValue && !m_bInCertDigest) ++} ++ ++void SAL_CALL XSecParser::startElement( ++ const OUString& rName, ++ const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs ) ++{ ++ assert(m_pNamespaceMap); ++ std::unique_ptr<SvXMLNamespaceMap> pRewindMap( ++ SvXMLImport::processNSAttributes(m_pNamespaceMap, nullptr, xAttribs)); ++ ++ OUString localName; ++ sal_uInt16 const nPrefix(m_pNamespaceMap->GetKeyByAttrName(rName, &localName)); ++ ++ std::unique_ptr<Context> pContext; ++ ++ if (m_ContextStack.empty()) + { +- m_ouDigestValue += aChars; ++ if ((nPrefix == XML_NAMESPACE_DSIG || nPrefix == XML_NAMESPACE_DSIG_OOO) ++ && localName == "document-signatures") ++ { ++ pContext.reset(new DsigSignaturesContext(*this, std::move(pRewindMap))); ++ } ++ else ++ { ++ throw css::xml::sax::SAXException( ++ "xmlsecurity: unexpected root element", nullptr, ++ css::uno::Any()); ++ } + } +- else if (m_bInDate) ++ else + { +- m_ouDate += aChars; ++ pContext = m_ContextStack.top()->CreateChildContext( ++ std::move(pRewindMap), nPrefix, localName); + } +- else if (m_bInDescription) ++ ++ m_ContextStack.push(std::move(pContext)); ++ assert(!pRewindMap); ++ ++ try + { +- m_ouDescription += aChars; ++ m_ContextStack.top()->StartElement(xAttribs); ++ ++ if (m_xNextHandler.is()) ++ { ++ m_xNextHandler->startElement(rName, xAttribs); ++ } + } +- else if (m_bInCertDigest) +- { +- m_ouCertDigest += aChars; ++ catch (css::uno::Exception& ) ++ {//getCaughtException MUST be the first line in the catch block ++ css::uno::Any exc = cppu::getCaughtException(); ++ throw css::xml::sax::SAXException( ++ "xmlsecurity: Exception in XSecParser::startElement", ++ nullptr, exc); + } +- else if (m_bInEncapsulatedX509Certificate) ++ catch (...) + { +- m_ouEncapsulatedX509Certificate += aChars; ++ throw css::xml::sax::SAXException( ++ "xmlsecurity: unexpected exception in XSecParser::startElement", nullptr, ++ css::uno::Any()); + } +- else if (m_bInSigningTime) ++} ++ ++void SAL_CALL XSecParser::endElement(const OUString& rName) ++{ ++ assert(!m_ContextStack.empty()); // this should be checked by sax parser? ++ ++ try + { +- m_ouDate += aChars; ++ m_ContextStack.top()->EndElement(); ++ ++ if (m_xNextHandler.is()) ++ { ++ m_xNextHandler->endElement(rName); ++ } + } +- else if (m_bInSignatureLineId) +- { +- m_ouSignatureLineId += aChars; ++ catch (css::uno::Exception& ) ++ {//getCaughtException MUST be the first line in the catch block ++ css::uno::Any exc = cppu::getCaughtException(); ++ throw css::xml::sax::SAXException( ++ "xmlsecurity: Exception in XSecParser::endElement", ++ nullptr, exc); + } +- else if (m_bInSignatureLineValidImage) ++ catch (...) + { +- m_ouSignatureLineValidImage += aChars; ++ throw css::xml::sax::SAXException( ++ "xmlsecurity: unexpected exception in XSecParser::endElement", nullptr, ++ css::uno::Any()); + } +- else if (m_bInSignatureLineInvalidImage) ++ ++ if (m_ContextStack.top()->m_pOldNamespaceMap) + { +- m_ouSignatureLineInvalidImage += aChars; ++ m_pNamespaceMap = std::move(m_ContextStack.top()->m_pOldNamespaceMap); + } ++ m_ContextStack.pop(); ++} ++ ++void SAL_CALL XSecParser::characters(const OUString& rChars) ++{ ++ assert(!m_ContextStack.empty()); // this should be checked by sax parser? ++ m_ContextStack.top()->Characters(rChars); + + if (m_xNextHandler.is()) + { +- m_xNextHandler->characters(aChars); ++ m_xNextHandler->characters(rChars); + } + } + +diff --git a/xmlsecurity/source/helper/xsecparser.hxx b/xmlsecurity/source/helper/xsecparser.hxx +index d9b079aa3116..93efcb766e3e 100644 +--- a/xmlsecurity/source/helper/xsecparser.hxx ++++ b/xmlsecurity/source/helper/xsecparser.hxx +@@ -25,6 +25,10 @@ + + #include <cppuhelper/implbase.hxx> + ++#include <xmloff/nmspmap.hxx> ++ ++#include <stack> ++ + class XMLSignatureHelper; + class XSecController; + +@@ -48,47 +52,59 @@ class XSecParser: public cppu::WeakImplHelper + ******************************************************************************/ + { + friend class XSecController; ++public: ++ class Context; + private: ++ class UnknownContext; ++ class LoPGPOwnerContext; ++ class DsPGPKeyPacketContext; ++ class DsPGPKeyIDContext; ++ class DsPGPDataContext; ++ class DsX509CertificateContext; ++ class DsX509SerialNumberContext; ++ class DsX509IssuerNameContext; ++ class DsX509IssuerSerialContext; ++ class DsX509DataContext; ++ class DsKeyInfoContext; ++ class DsSignatureValueContext; ++ class DsDigestValueContext; ++ class DsDigestMethodContext; ++ class DsTransformContext; ++ class DsTransformsContext; ++ class DsReferenceContext; ++ class DsSignatureMethodContext; ++ class DsSignedInfoContext; ++ class XadesEncapsulatedX509CertificateContext; ++ class XadesCertificateValuesContext; ++ class XadesUnsignedSignaturePropertiesContext; ++ class XadesUnsignedPropertiesContext; ++ class LoSignatureLineIdContext; ++ class LoSignatureLineValidImageContext; ++ class LoSignatureLineInvalidImageContext; ++ class LoSignatureLineContext; ++ class XadesCertDigestContext; ++ class XadesCertContext; ++ class XadesSigningCertificateContext; ++ class XadesSigningTimeContext; ++ class XadesSignedSignaturePropertiesContext; ++ class XadesSignedPropertiesContext; ++ class XadesQualifyingPropertiesContext; ++ class DcDateContext; ++ class DcDescriptionContext; ++ class DsSignaturePropertyContext; ++ class DsSignaturePropertiesContext; ++ class DsObjectContext; ++ class DsSignatureContext; ++ class DsigSignaturesContext; ++ + /* + * the following members are used to reserve the signature information, + * including X509IssuerName, X509SerialNumber, and X509Certificate,etc. + */ +- OUString m_ouX509IssuerName; +- OUString m_ouX509SerialNumber; +- OUString m_ouX509Certificate; +- OUString m_ouGpgCertificate; +- OUString m_ouGpgKeyID; +- OUString m_ouGpgOwner; +- OUString m_ouCertDigest; +- OUString m_ouEncapsulatedX509Certificate; +- OUString m_ouDigestValue; +- OUString m_ouSignatureValue; + OUString m_ouDate; +- /// Characters of a <dc:description> element, as just read from XML. +- OUString m_ouDescription; +- OUString m_ouSignatureLineId; +- OUString m_ouSignatureLineValidImage; +- OUString m_ouSignatureLineInvalidImage; + +- /* +- * whether inside a particular element +- */ +- bool m_bInX509IssuerName; +- bool m_bInX509SerialNumber; +- bool m_bInX509Certificate; +- bool m_bInGpgCertificate; +- bool m_bInGpgKeyID; +- bool m_bInGpgOwner; +- bool m_bInCertDigest; +- bool m_bInEncapsulatedX509Certificate; +- bool m_bInSigningTime; +- bool m_bInDigestValue; +- bool m_bInSignatureValue; +- bool m_bInDate; +- bool m_bInDescription; +- bool m_bInSignatureLineId; +- bool m_bInSignatureLineValidImage; +- bool m_bInSignatureLineInvalidImage; ++ std::stack<std::unique_ptr<Context>> m_ContextStack; ++ std::unique_ptr<SvXMLNamespaceMap> m_pNamespaceMap; + + /* + * the XSecController collaborating with XSecParser +@@ -101,22 +117,9 @@ private: + css::uno::Reference< + css::xml::sax::XDocumentHandler > m_xNextHandler; + +- /* +- * this string is used to remember the current handled reference's URI, +- * +- * because it can be decided whether a stream reference is xml based or binary based +- * only after the Transforms element is read in, so we have to reserve the reference's +- * URI when the startElement event is met. +- */ +- OUString m_currentReferenceURI; +- bool m_bReferenceUnresolved; +- +- // Relevant for ODF. The digest algorithm selected by the current DigestMethod element's +- // Algorithm attribute in the current Reference element. From css::xml::crypto::DigestID. +- sal_Int32 m_nReferenceDigestID; + XMLSignatureHelper& m_rXMLSignatureHelper; + +-private: ++ OUString HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs); + static OUString getIdAttr(const css::uno::Reference< + css::xml::sax::XAttributeList >& xAttribs ); + +-- +cgit v1.2.1 + |