Blame SOURCES/0006-xmlsecurity-replace-OOXMLSecParser-implementation.patch

be40d7
From 78f208c5aa615ccf6738d2a174564269e5f3e0ab Mon Sep 17 00:00:00 2001
24cd51
From: Michael Stahl <michael.stahl@allotropia.de>
24cd51
Date: Tue, 30 Mar 2021 17:37:31 +0200
be40d7
Subject: [PATCH] xmlsecurity: replace OOXMLSecParser implementation
24cd51
24cd51
This is similar to 12b15be8f4f930a04d8056b9219ac969b42a9784 and following
24cd51
commits, but OOXMLSecParser has some differences to XSecParser, such as
24cd51
using a ds:Manifest, and requires a couple extra namespaces.
24cd51
24cd51
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113381
24cd51
Tested-by: Jenkins
24cd51
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
24cd51
(cherry picked from commit cc1d19f7bbaefa5fb22ebd1344112755068b93c9)
24cd51
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113360
24cd51
(cherry picked from commit 5e2c137c27310e76050f2247077b1311baee4381)
24cd51
24cd51
Change-Id: I56e39d9609db8fcad50ca1632ff482c1f0a30ff5
24cd51
---
24cd51
 include/xmloff/xmlnmspe.hxx                  |    3 +
24cd51
 xmlsecurity/source/helper/ooxmlsecparser.cxx | 1473 +++++++++++++++---
be40d7
 xmlsecurity/source/helper/ooxmlsecparser.hxx |   78 +-
be40d7
 3 files changed, 1314 insertions(+), 240 deletions(-)
24cd51
24cd51
diff --git a/include/xmloff/xmlnmspe.hxx b/include/xmloff/xmlnmspe.hxx
24cd51
index 302a134f92fe..bebb1d656b40 100644
24cd51
--- a/include/xmloff/xmlnmspe.hxx
24cd51
+++ b/include/xmloff/xmlnmspe.hxx
24cd51
@@ -73,6 +73,9 @@ XML_NAMESPACE( XML_NAMESPACE_DSIG,            39U )
24cd51
 XML_NAMESPACE( XML_NAMESPACE_DS,              40U )
24cd51
 XML_NAMESPACE( XML_NAMESPACE_XADES132,        41U )
24cd51
 XML_NAMESPACE( XML_NAMESPACE_XADES141,        42U )
24cd51
+// OOXML digital signature extension namespaces, also based on xmldsig-core
24cd51
+XML_NAMESPACE( XML_NAMESPACE_MDSSI,           43U )
24cd51
+XML_NAMESPACE( XML_NAMESPACE_MSODIGSIG,       44U )
24cd51
 
24cd51
 // namespaces for odf extended formats
24cd51
 
24cd51
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx
24cd51
index a25872fc057d..42f226f57d14 100644
24cd51
--- a/xmlsecurity/source/helper/ooxmlsecparser.cxx
24cd51
+++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx
24cd51
@@ -11,32 +11,1241 @@
24cd51
 #include "ooxmlsecparser.hxx"
24cd51
 #include <xmlsignaturehelper.hxx>
24cd51
 #include <xsecctl.hxx>
24cd51
+
24cd51
+#include <xmloff/xmlnmspe.hxx>
24cd51
+#include <xmloff/xmlimp.hxx>
24cd51
+
24cd51
+#include <com/sun/star/xml/sax/SAXException.hpp>
24cd51
+
24cd51
 #include <sal/log.hxx>
24cd51
 
24cd51
-using namespace com::sun::star;
24cd51
+using namespace com::sun::star;
24cd51
+
24cd51
+class OOXMLSecParser::Context
24cd51
+{
24cd51
+    protected:
24cd51
+        friend class OOXMLSecParser;
24cd51
+        OOXMLSecParser & m_rParser;
24cd51
+    private:
24cd51
+        std::unique_ptr<SvXMLNamespaceMap> m_pOldNamespaceMap;
24cd51
+
24cd51
+    public:
24cd51
+        Context(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : m_rParser(rParser)
24cd51
+            , m_pOldNamespaceMap(std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual ~Context() = default;
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement()
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/);
24cd51
+
24cd51
+        virtual void Characters(OUString const& /*rChars*/)
24cd51
+        {
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+// it's possible that an unsupported element has an Id attribute and a
24cd51
+// ds:Reference digesting it - probably this means XSecController needs to know
24cd51
+// about it. (For known elements, the Id attribute is only processed according
24cd51
+// to the schema.)
24cd51
+class OOXMLSecParser::UnknownContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    public:
24cd51
+        UnknownContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            m_rParser.HandleIdAttr(xAttrs);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+auto OOXMLSecParser::Context::CreateChildContext(
24cd51
+    std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+    sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/)
24cd51
+-> std::unique_ptr<Context>
24cd51
+{
24cd51
+    // default: create new base context
24cd51
+    return std::make_unique<UnknownContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+}
24cd51
+
24cd51
+/**
24cd51
+note: anything in ds:Object should be trusted *only* if there is a ds:Reference
24cd51
+      to it so it is signed (exception: the xades:EncapsulatedX509Certificate).
24cd51
+      ds:SignedInfo precedes all ds:Object.
24cd51
+
24cd51
+      There may be multiple ds:Signature for purpose of counter-signatures
24cd51
+      but the way XAdES describes these, only the ds:SignatureValue element
24cd51
+      would be referenced, so requiring a ds:Reference for anything in
24cd51
+      ds:Object shouldn't cause issues.
24cd51
+ */
24cd51
+class OOXMLSecParser::ReferencedContextImpl
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    protected:
24cd51
+        bool m_isReferenced;
24cd51
+
24cd51
+    public:
24cd51
+        ReferencedContextImpl(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_isReferenced(isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        OUString CheckIdAttrReferenced(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
24cd51
+        {
24cd51
+            OUString const id(m_rParser.HandleIdAttr(xAttrs));
24cd51
+            if (!id.isEmpty() && m_rParser.m_pXSecController->haveReferenceForId(id))
24cd51
+            {
24cd51
+                m_isReferenced = true;
24cd51
+            }
24cd51
+            return id;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsX509CertificateContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        DsX509CertificateContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_rValue += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsX509SerialNumberContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        DsX509SerialNumberContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_rValue += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsX509IssuerNameContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        DsX509IssuerNameContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_rValue += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsX509IssuerSerialContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rX509IssuerName;
24cd51
+        OUString & m_rX509SerialNumber;
24cd51
+
24cd51
+    public:
24cd51
+        DsX509IssuerSerialContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rIssuerName, OUString & rSerialNumber)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rX509IssuerName(rIssuerName)
24cd51
+            , m_rX509SerialNumber(rSerialNumber)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerName")
24cd51
+            {
24cd51
+                return std::make_unique<DsX509IssuerNameContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509IssuerName);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509SerialNumber")
24cd51
+            {
24cd51
+                return std::make_unique<DsX509SerialNumberContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509SerialNumber);
24cd51
+            }
24cd51
+            // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+/// can't be sure what is supposed to happen here because the spec is clear as mud
24cd51
+class OOXMLSecParser::DsX509DataContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        // sigh... "No ordering is implied by the above constraints."
24cd51
+        // so store the ball of mud in vectors and try to figure it out later.
24cd51
+        std::vector<std::pair<OUString, OUString>> m_X509IssuerSerials;
24cd51
+        std::vector<OUString> m_X509Certificates;
24cd51
+
24cd51
+    public:
24cd51
+        DsX509DataContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            m_rParser.m_pXSecController->setX509Data(m_X509IssuerSerials, m_X509Certificates);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerSerial")
24cd51
+            {
24cd51
+                m_X509IssuerSerials.emplace_back();
24cd51
+                return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerSerials.back().first, m_X509IssuerSerials.back().second);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509Certificate")
24cd51
+            {
24cd51
+                m_X509Certificates.emplace_back();
24cd51
+                return std::make_unique<DsX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_X509Certificates.back());
24cd51
+            }
24cd51
+            // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsKeyInfoContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    public:
24cd51
+        DsKeyInfoContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            m_rParser.HandleIdAttr(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509Data")
24cd51
+            {
24cd51
+                return std::make_unique<DsX509DataContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            // missing: ds:PGPData
24cd51
+            // missing: ds:KeyName, ds:KeyValue, ds:RetrievalMethod, ds:SPKIData, ds:MgmtData
24cd51
+            // (old code would read ds:Transform inside ds:RetrievalMethod but
24cd51
+            // presumably that was a bug)
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsSignatureValueContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString m_Value;
24cd51
+
24cd51
+    public:
24cd51
+        DsSignatureValueContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            m_rParser.HandleIdAttr(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            m_rParser.m_pXSecController->setSignatureValue(m_Value);
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_Value += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsDigestValueContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        DsDigestValueContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override
24cd51
+        {
24cd51
+            m_rValue.clear();
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_rValue += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsDigestMethodContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        sal_Int32 & m_rReferenceDigestID;
24cd51
+
24cd51
+    public:
24cd51
+        DsDigestMethodContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                sal_Int32 & rReferenceDigestID)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rReferenceDigestID(rReferenceDigestID)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
24cd51
+
24cd51
+            SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" );
24cd51
+            if (!ouAlgorithm.isEmpty())
24cd51
+            {
24cd51
+                SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1
24cd51
+                             && ouAlgorithm != ALGO_XMLDSIGSHA256
24cd51
+                             && ouAlgorithm != ALGO_XMLDSIGSHA512,
24cd51
+                             "xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512");
24cd51
+                if (ouAlgorithm == ALGO_XMLDSIGSHA1)
24cd51
+                    m_rReferenceDigestID = css::xml::crypto::DigestID::SHA1;
24cd51
+                else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
24cd51
+                    m_rReferenceDigestID = css::xml::crypto::DigestID::SHA256;
24cd51
+                else if (ouAlgorithm == ALGO_XMLDSIGSHA512)
24cd51
+                    m_rReferenceDigestID = css::xml::crypto::DigestID::SHA512;
24cd51
+                else
24cd51
+                    m_rReferenceDigestID = 0;
24cd51
+            }
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsTransformContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        bool & m_rIsC14N;
24cd51
+
24cd51
+    public:
24cd51
+        DsTransformContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool & rIsC14N)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rIsC14N(rIsC14N)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            OUString aAlgorithm = xAttrs->getValueByName("Algorithm");
24cd51
+
24cd51
+            if (aAlgorithm == ALGO_RELATIONSHIP)
24cd51
+            {
24cd51
+                m_rIsC14N = true;
24cd51
+            }
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsTransformsContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        bool & m_rIsC14N;
24cd51
+
24cd51
+    public:
24cd51
+        DsTransformsContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool & rIsC14N)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rIsC14N(rIsC14N)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Transform")
24cd51
+            {
24cd51
+                return std::make_unique<DsTransformContext>(m_rParser, std::move(pOldNamespaceMap), m_rIsC14N);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsReferenceContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString m_URI;
24cd51
+        OUString m_Type;
24cd51
+        OUString m_DigestValue;
24cd51
+        bool m_IsC14N = false;
24cd51
+        // Relevant for ODF. The digest algorithm selected by the DigestMethod
24cd51
+        // element's Algorithm attribute. @see css::xml::crypto::DigestID.
24cd51
+        sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA256;
24cd51
+
24cd51
+    public:
24cd51
+        DsReferenceContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            m_rParser.HandleIdAttr(xAttrs);
24cd51
+
24cd51
+            m_URI = xAttrs->getValueByName("URI");
24cd51
+            SAL_WARN_IF(m_URI.isEmpty(), "xmlsecurity.helper", "URI is empty");
24cd51
+            // Remember the type of this reference.
24cd51
+            m_Type = xAttrs->getValueByName("Type");
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            if (m_URI.startsWith("#"))
24cd51
+            {
24cd51
+                /*
24cd51
+                * remove the first character '#' from the attribute value
24cd51
+                */
24cd51
+                m_rParser.m_pXSecController->addReference(m_URI.copy(1), m_nReferenceDigestID, m_Type);
24cd51
+            }
24cd51
+            else
24cd51
+            {
24cd51
+                if (m_IsC14N) // this is determined by nested ds:Transform
24cd51
+                {
24cd51
+                    m_rParser.m_pXSecController->addStreamReference(m_URI, false, m_nReferenceDigestID);
24cd51
+                }
24cd51
+                else
24cd51
+            /*
24cd51
+            * it must be an octet stream
24cd51
+            */
24cd51
+                {
24cd51
+                    m_rParser.m_pXSecController->addStreamReference(m_URI, true, m_nReferenceDigestID);
24cd51
+                }
24cd51
+            }
24cd51
+
24cd51
+            m_rParser.m_pXSecController->setDigestValue(m_nReferenceDigestID, m_DigestValue);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Transforms")
24cd51
+            {
24cd51
+                return std::make_unique<DsTransformsContext>(m_rParser, std::move(pOldNamespaceMap), m_IsC14N);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
24cd51
+            {
24cd51
+                return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_nReferenceDigestID);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
24cd51
+            {
24cd51
+                return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_DigestValue);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsSignatureMethodContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    public:
24cd51
+        DsSignatureMethodContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
24cd51
+            if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
24cd51
+                || ouAlgorithm == ALGO_ECDSASHA512)
24cd51
+            {
24cd51
+                m_rParser.m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
24cd51
+            }
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsSignedInfoContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    public:
24cd51
+        DsSignedInfoContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            m_rParser.HandleIdAttr(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            m_rParser.m_pXSecController->setReferenceCount();
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureMethod")
24cd51
+            {
24cd51
+                return std::make_unique<DsSignatureMethodContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
24cd51
+            {
24cd51
+                return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            // missing: ds:CanonicalizationMethod
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::XadesCertDigestContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rDigestValue;
24cd51
+        sal_Int32 & m_rReferenceDigestID;
24cd51
+
24cd51
+    public:
24cd51
+        XadesCertDigestContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rDigestValue, sal_Int32 & rReferenceDigestID)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rDigestValue(rDigestValue)
24cd51
+            , m_rReferenceDigestID(rReferenceDigestID)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
24cd51
+            {
24cd51
+                return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_rReferenceDigestID);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
24cd51
+            {
24cd51
+                return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_rDigestValue);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::XadesCertContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    private:
24cd51
+        sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1;
24cd51
+        OUString m_CertDigest;
24cd51
+        OUString m_X509IssuerName;
24cd51
+        OUString m_X509SerialNumber;
24cd51
+
24cd51
+    public:
24cd51
+        XadesCertContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            if (m_isReferenced)
24cd51
+            {
24cd51
+                m_rParser.m_pXSecController->setX509CertDigest(m_CertDigest, m_nReferenceDigestID, m_X509IssuerName, m_X509SerialNumber);
24cd51
+            }
24cd51
+            else
24cd51
+            {
24cd51
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned xades:Cert");
24cd51
+            }
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertDigest")
24cd51
+            {
24cd51
+                return std::make_unique<XadesCertDigestContext>(m_rParser, std::move(pOldNamespaceMap), m_CertDigest, m_nReferenceDigestID);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "IssuerSerial")
24cd51
+            {
24cd51
+                return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerName, m_X509SerialNumber);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::XadesSigningCertificateContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    public:
24cd51
+        XadesSigningCertificateContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "Cert")
24cd51
+            {
24cd51
+                return std::make_unique<XadesCertContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::XadesSigningTimeContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    private:
24cd51
+        OUString m_Value;
24cd51
+
24cd51
+    public:
24cd51
+        XadesSigningTimeContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            if (m_isReferenced)
24cd51
+            {
24cd51
+                m_rParser.m_pXSecController->setDate("", m_Value);
24cd51
+            }
24cd51
+            else
24cd51
+            {
24cd51
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned SigningTime");
24cd51
+            }
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_Value += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::XadesSignedSignaturePropertiesContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    public:
24cd51
+        XadesSignedSignaturePropertiesContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            CheckIdAttrReferenced(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningTime")
24cd51
+            {
24cd51
+                return std::make_unique<XadesSigningTimeContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningCertificate")
24cd51
+            {
24cd51
+                return std::make_unique<XadesSigningCertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            // missing: xades:SignaturePolicyIdentifier, xades:SignatureProductionPlace, xades:SignerRole
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::XadesSignedPropertiesContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    public:
24cd51
+        XadesSignedPropertiesContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            CheckIdAttrReferenced(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedSignatureProperties")
24cd51
+            {
24cd51
+                return std::make_unique<XadesSignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            // missing: xades:SignedDataObjectProperties
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::XadesQualifyingPropertiesContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    public:
24cd51
+        XadesQualifyingPropertiesContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            CheckIdAttrReferenced(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedProperties")
24cd51
+            {
24cd51
+                return std::make_unique<XadesSignedPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            // missing: xades:UnsignedSignatureProperties
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::MsodigsigSetupIDContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        MsodigsigSetupIDContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_rValue += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::MsodigsigSignatureCommentsContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        MsodigsigSignatureCommentsContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_rValue += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::MsodigsigSignatureInfoV1Context
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    private:
24cd51
+        OUString m_SetupID;
24cd51
+        OUString m_SignatureComments;
24cd51
+
24cd51
+    public:
24cd51
+        MsodigsigSignatureInfoV1Context(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            CheckIdAttrReferenced(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SetupID")
24cd51
+            {
24cd51
+                return std::make_unique<MsodigsigSetupIDContext>(m_rParser, std::move(pOldNamespaceMap), m_SetupID);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SignatureComments")
24cd51
+            {
24cd51
+                return std::make_unique<MsodigsigSignatureCommentsContext>(m_rParser, std::move(pOldNamespaceMap), m_SignatureComments);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            if (m_isReferenced)
24cd51
+            {
24cd51
+                if (!m_SetupID.isEmpty())
24cd51
+                {
24cd51
+                    m_rParser.m_pXSecController->setSignatureLineId(m_SetupID);
24cd51
+                }
24cd51
+                if (!m_SignatureComments.isEmpty())
24cd51
+                {
24cd51
+                    m_rParser.m_pXSecController->setDescription("", m_SignatureComments);
24cd51
+
24cd51
+                }
24cd51
+            }
24cd51
+            else
24cd51
+            {
24cd51
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureInfoV1");
24cd51
+            }
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::MdssiValueContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        MdssiValueContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_rValue += rChars;
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::MdssiSignatureTimeContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    private:
24cd51
+        OUString & m_rValue;
24cd51
+
24cd51
+    public:
24cd51
+        MdssiSignatureTimeContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                OUString & rValue)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+            , m_rValue(rValue)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_MDSSI && rName == "Value")
24cd51
+            {
24cd51
+                return std::make_unique<MdssiValueContext>(m_rParser, std::move(pOldNamespaceMap), m_rValue);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+
24cd51
+class OOXMLSecParser::DsSignaturePropertyContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    private:
24cd51
+        enum class SignatureProperty { Unknown, Date, Info };
24cd51
+        SignatureProperty m_Property = SignatureProperty::Unknown;
24cd51
+        OUString m_Id;
24cd51
+        OUString m_Value;
24cd51
+
24cd51
+    public:
24cd51
+        DsSignaturePropertyContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            m_Id = CheckIdAttrReferenced(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            if (m_isReferenced)
24cd51
+            {
24cd51
+                switch (m_Property)
24cd51
+                {
24cd51
+                    case SignatureProperty::Unknown:
24cd51
+                        SAL_INFO("xmlsecurity.helper", "Unknown property in ds:Object ignored");
24cd51
+                        break;
24cd51
+                    case SignatureProperty::Info:
24cd51
+                        break; // handled by child context
24cd51
+                    case SignatureProperty::Date:
24cd51
+                        m_rParser.m_pXSecController->setDate(m_Id, m_Value);
24cd51
+                        break;
24cd51
+                }
24cd51
+            }
24cd51
+            else
24cd51
+            {
24cd51
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureProperty");
24cd51
+            }
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_MDSSI && rName == "SignatureTime")
24cd51
+            {
24cd51
+                m_Property = SignatureProperty::Date;
24cd51
+                return std::make_unique<MdssiSignatureTimeContext>(m_rParser, std::move(pOldNamespaceMap), m_Value);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SignatureInfoV1")
24cd51
+            {
24cd51
+                return std::make_unique<MsodigsigSignatureInfoV1Context>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsSignaturePropertiesContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    public:
24cd51
+        DsSignaturePropertiesContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            CheckIdAttrReferenced(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperty")
24cd51
+            {
24cd51
+                return std::make_unique<DsSignaturePropertyContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsManifestContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+    public:
24cd51
+        DsManifestContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+                bool const isReferenced)
24cd51
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            CheckIdAttrReferenced(xAttrs);
24cd51
+        }
24cd51
+
24cd51
+#if 0
24cd51
+        ???
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            m_rParser.m_pXSecController->setReferenceCount();
24cd51
+        }
24cd51
+#endif
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
24cd51
+            {
24cd51
+                return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            // missing: ds:CanonicalizationMethod
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsObjectContext
24cd51
+    : public OOXMLSecParser::ReferencedContextImpl
24cd51
+{
24cd51
+        enum class Mode { Default, ValidSignatureLineImage, InvalidSignatureLineImage };
24cd51
+        Mode m_Mode = Mode::Default;
24cd51
+        OUString m_Value;
24cd51
+
24cd51
+    public:
24cd51
+        DsObjectContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            // init with "false" here - the Signature element can't be referenced by its child
24cd51
+            : OOXMLSecParser::ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), false)
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            OUString const id(CheckIdAttrReferenced(xAttrs));
24cd51
+            if (id == "idValidSigLnImg")
24cd51
+            {
24cd51
+                m_Mode = Mode::ValidSignatureLineImage;
24cd51
+            }
24cd51
+            else if (id == "idInvalidSigLnImg")
24cd51
+            {
24cd51
+                m_Mode = Mode::InvalidSignatureLineImage;
24cd51
+            }
24cd51
+        }
24cd51
+
24cd51
+        virtual void EndElement() override
24cd51
+        {
24cd51
+            switch (m_Mode)
24cd51
+            {
24cd51
+                case Mode::ValidSignatureLineImage:
24cd51
+                    if (m_isReferenced)
24cd51
+                    {
24cd51
+                        m_rParser.m_pXSecController->setValidSignatureImage(m_Value);
24cd51
+                    }
24cd51
+                    else
24cd51
+                    {
24cd51
+                        SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineValidImage");
24cd51
+                    }
24cd51
+                    break;
24cd51
+                case Mode::InvalidSignatureLineImage:
24cd51
+                    if (m_isReferenced)
24cd51
+                    {
24cd51
+                        m_rParser.m_pXSecController->setInvalidSignatureImage(m_Value);
24cd51
+                    }
24cd51
+                    else
24cd51
+                    {
24cd51
+                        SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineInvalidImage");
24cd51
+                    }
24cd51
+                    break;
24cd51
+                case Mode::Default:
24cd51
+                    break;
24cd51
+            }
24cd51
+        }
24cd51
+
24cd51
+        virtual void Characters(OUString const& rChars) override
24cd51
+        {
24cd51
+            m_Value += rChars;
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperties")
24cd51
+            {
24cd51
+                return std::make_unique<DsSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "QualifyingProperties")
24cd51
+            {
24cd51
+                return std::make_unique<XadesQualifyingPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Manifest")
24cd51
+            {
24cd51
+                return std::make_unique<DsManifestContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
+class OOXMLSecParser::DsSignatureContext
24cd51
+    : public OOXMLSecParser::Context
24cd51
+{
24cd51
+    public:
24cd51
+        DsSignatureContext(OOXMLSecParser & rParser,
24cd51
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
24cd51
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
24cd51
+        {
24cd51
+        }
24cd51
+
24cd51
+        virtual void StartElement(
24cd51
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
24cd51
+        {
24cd51
+            OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs));
24cd51
+            m_rParser.m_rXMLSignatureHelper.StartVerifySignatureElement();
24cd51
+            m_rParser.m_pXSecController->addSignature();
24cd51
+            if (!ouIdAttr.isEmpty())
24cd51
+            {
24cd51
+                m_rParser.m_pXSecController->setId( ouIdAttr );
24cd51
+            }
24cd51
+        }
24cd51
+
24cd51
+        virtual std::unique_ptr<Context> CreateChildContext(
24cd51
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
24cd51
+            sal_uInt16 const nNamespace, OUString const& rName) override
24cd51
+        {
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignedInfo")
24cd51
+            {
24cd51
+                return std::make_unique<DsSignedInfoContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureValue")
24cd51
+            {
24cd51
+                return std::make_unique<DsSignatureValueContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "KeyInfo")
24cd51
+            {
24cd51
+                return std::make_unique<DsKeyInfoContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Object")
24cd51
+            {
24cd51
+                return std::make_unique<DsObjectContext>(m_rParser, std::move(pOldNamespaceMap));
24cd51
+            }
24cd51
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
24cd51
+        }
24cd51
+};
24cd51
+
24cd51
 
24cd51
 OOXMLSecParser::OOXMLSecParser(XMLSignatureHelper& rXMLSignatureHelper, XSecController* pXSecController)
24cd51
-    : m_pXSecController(pXSecController)
24cd51
-    ,m_bInDigestValue(false)
24cd51
-    ,m_bInSignatureValue(false)
24cd51
-    ,m_bInX509Certificate(false)
24cd51
-    ,m_bInMdssiValue(false)
24cd51
-    ,m_bInSignatureComments(false)
24cd51
-    ,m_bInX509IssuerName(false)
24cd51
-    ,m_bInX509SerialNumber(false)
24cd51
-    ,m_bInCertDigest(false)
24cd51
-    ,m_bInValidSignatureImage(false)
24cd51
-    ,m_bInInvalidSignatureImage(false)
24cd51
-    ,m_bInSignatureLineId(false)
24cd51
-    ,m_bReferenceUnresolved(false)
24cd51
+    : m_pNamespaceMap(new SvXMLNamespaceMap)
24cd51
+    , m_pXSecController(pXSecController)
24cd51
     ,m_rXMLSignatureHelper(rXMLSignatureHelper)
24cd51
 {
24cd51
+    using namespace xmloff::token;
24cd51
+    m_pNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
24cd51
+    m_pNamespaceMap->Add( "_ds", GetXMLToken(XML_N_DS), XML_NAMESPACE_DS );
24cd51
+    m_pNamespaceMap->Add( "_xades132", GetXMLToken(XML_N_XADES132), XML_NAMESPACE_XADES132);
24cd51
+    m_pNamespaceMap->Add( "_xades141", GetXMLToken(XML_N_XADES141), XML_NAMESPACE_XADES141);
24cd51
+    m_pNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
24cd51
+    m_pNamespaceMap->Add( "_mdssi", NS_MDSSI, XML_NAMESPACE_MDSSI );
24cd51
+    m_pNamespaceMap->Add( "_msodigsig", "http://schemas.microsoft.com/office/2006/digsig", XML_NAMESPACE_MSODIGSIG );
24cd51
+    m_pNamespaceMap->Add( "_office_libo",
24cd51
+                         GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
24cd51
 }
24cd51
 
24cd51
 OOXMLSecParser::~OOXMLSecParser()
24cd51
 {
24cd51
 }
24cd51
 
24cd51
+OUString OOXMLSecParser::HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
24cd51
+{
24cd51
+    OUString const aId = xAttrs->getValueByName("Id");
24cd51
+    if (!aId.isEmpty())
24cd51
+    {
24cd51
+        m_pXSecController->collectToVerify(aId);
24cd51
+    }
24cd51
+    return aId;
24cd51
+}
24cd51
+
24cd51
 void SAL_CALL OOXMLSecParser::startDocument()
24cd51
 {
24cd51
     if (m_xNextHandler.is())
24cd51
@@ -51,231 +1260,69 @@ void SAL_CALL OOXMLSecParser::endDocument()
24cd51
 
24cd51
 void SAL_CALL OOXMLSecParser::startElement(const OUString& rName, const uno::Reference<xml::sax::XAttributeList>& xAttribs)
24cd51
 {
24cd51
-    OUString aId = xAttribs->getValueByName("Id");
24cd51
-    if (!aId.isEmpty())
24cd51
-        m_pXSecController->collectToVerify(aId);
24cd51
+    assert(m_pNamespaceMap);
24cd51
+    std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
24cd51
+        SvXMLImport::processNSAttributes(m_pNamespaceMap, nullptr, xAttribs));
24cd51
 
24cd51
-    if (rName == "Signature")
24cd51
-    {
24cd51
-        m_rXMLSignatureHelper.StartVerifySignatureElement();
24cd51
-        m_pXSecController->addSignature();
24cd51
-        if (!aId.isEmpty())
24cd51
-            m_pXSecController->setId(aId);
24cd51
-    }
24cd51
-    else if (rName == "SignatureMethod")
24cd51
-    {
24cd51
-        OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
24cd51
-        if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
24cd51
-            || ouAlgorithm == ALGO_ECDSASHA512)
24cd51
-            m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
24cd51
-    }
24cd51
-    else if (rName == "Reference")
24cd51
-    {
24cd51
-        OUString aURI = xAttribs->getValueByName("URI");
24cd51
-        if (aURI.startsWith("#"))
24cd51
-            m_pXSecController->addReference(aURI.copy(1), xml::crypto::DigestID::SHA1, OUString());
24cd51
-        else
24cd51
-        {
24cd51
-            m_aReferenceURI = aURI;
24cd51
-            m_bReferenceUnresolved = true;
24cd51
-        }
24cd51
-    }
24cd51
-    else if (rName == "Transform")
24cd51
-    {
24cd51
-        if (m_bReferenceUnresolved)
24cd51
-        {
24cd51
-            OUString aAlgorithm = xAttribs->getValueByName("Algorithm");
24cd51
-            if (aAlgorithm == ALGO_RELATIONSHIP)
24cd51
-            {
24cd51
-                m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/false, /*nDigestID=*/xml::crypto::DigestID::SHA256);
24cd51
-                m_bReferenceUnresolved = false;
24cd51
-            }
24cd51
-        }
24cd51
-    }
24cd51
-    else if (rName == "DigestValue" && !m_bInCertDigest)
24cd51
-    {
24cd51
-        m_aDigestValue.clear();
24cd51
-        m_bInDigestValue = true;
24cd51
-    }
24cd51
-    else if (rName == "SignatureValue")
24cd51
-    {
24cd51
-        m_aSignatureValue.clear();
24cd51
-        m_bInSignatureValue = true;
24cd51
-    }
24cd51
-    else if (rName == "X509Certificate")
24cd51
-    {
24cd51
-        m_aX509Certificate.clear();
24cd51
-        m_bInX509Certificate = true;
24cd51
-    }
24cd51
-    else if (rName == "mdssi:Value")
24cd51
-    {
24cd51
-        m_aMdssiValue.clear();
24cd51
-        m_bInMdssiValue = true;
24cd51
-    }
24cd51
-    else if (rName == "SignatureComments")
24cd51
-    {
24cd51
-        m_aSignatureComments.clear();
24cd51
-        m_bInSignatureComments = true;
24cd51
-    }
24cd51
-    else if (rName == "X509IssuerName")
24cd51
-    {
24cd51
-        m_aX509IssuerName.clear();
24cd51
-        m_bInX509IssuerName = true;
24cd51
-    }
24cd51
-    else if (rName == "X509SerialNumber")
24cd51
-    {
24cd51
-        m_aX509SerialNumber.clear();
24cd51
-        m_bInX509SerialNumber = true;
24cd51
-    }
24cd51
-    else if (rName == "xd:CertDigest")
24cd51
-    {
24cd51
-        m_aCertDigest.clear();
24cd51
-        m_bInCertDigest = true;
24cd51
-    }
24cd51
-    else if (rName == "Object")
24cd51
+    OUString localName;
24cd51
+    sal_uInt16 const nPrefix(m_pNamespaceMap->GetKeyByAttrName(rName, &localName));
24cd51
+
24cd51
+    std::unique_ptr<Context> pContext;
24cd51
+
24cd51
+    if (m_ContextStack.empty())
24cd51
     {
24cd51
-        OUString sId = xAttribs->getValueByName("Id");
24cd51
-        if (sId == "idValidSigLnImg")
24cd51
-        {
24cd51
-            m_aValidSignatureImage.clear();
24cd51
-            m_bInValidSignatureImage = true;
24cd51
-        }
24cd51
-        else if (sId == "idInvalidSigLnImg")
24cd51
+        if (nPrefix == XML_NAMESPACE_DS
24cd51
+            && localName == "Signature")
24cd51
         {
24cd51
-            m_aInvalidSignatureImage.clear();
24cd51
-            m_bInInvalidSignatureImage = true;
24cd51
+            pContext.reset(new DsSignatureContext(*this, std::move(pRewindMap)));
24cd51
         }
24cd51
         else
24cd51
         {
24cd51
-            SAL_INFO("xmlsecurity.ooxml", "Unknown 'Object' child element: " << rName);
24cd51
+            throw css::xml::sax::SAXException(
24cd51
+                "xmlsecurity: unexpected root element", nullptr,
24cd51
+                css::uno::Any());
24cd51
         }
24cd51
     }
24cd51
-    else if (rName == "SetupID")
24cd51
-    {
24cd51
-        m_aSignatureLineId.clear();
24cd51
-        m_bInSignatureLineId = true;
24cd51
-    }
24cd51
     else
24cd51
     {
24cd51
-        SAL_INFO("xmlsecurity.ooxml", "Unknown xml element: " << rName);
24cd51
+        pContext = m_ContextStack.top()->CreateChildContext(
24cd51
+                std::move(pRewindMap), nPrefix, localName);
24cd51
     }
24cd51
 
24cd51
+    m_ContextStack.push(std::move(pContext));
24cd51
+    assert(!pRewindMap);
24cd51
+
24cd51
+    m_ContextStack.top()->StartElement(xAttribs);
24cd51
+
24cd51
     if (m_xNextHandler.is())
24cd51
+    {
24cd51
         m_xNextHandler->startElement(rName, xAttribs);
24cd51
+    }
24cd51
+
24cd51
 }
24cd51
 
24cd51
 void SAL_CALL OOXMLSecParser::endElement(const OUString& rName)
24cd51
 {
24cd51
-    if (rName == "SignedInfo")
24cd51
-        m_pXSecController->setReferenceCount();
24cd51
-    else if (rName == "Reference")
24cd51
-    {
24cd51
-        if (m_bReferenceUnresolved)
24cd51
-        {
24cd51
-            // No transform algorithm found, assume binary.
24cd51
-            m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/true, /*nDigestID=*/xml::crypto::DigestID::SHA256);
24cd51
-            m_bReferenceUnresolved = false;
24cd51
-        }
24cd51
-        m_pXSecController->setDigestValue(xml::crypto::DigestID::SHA256, m_aDigestValue);
24cd51
-    }
24cd51
-    else if (rName == "DigestValue" && !m_bInCertDigest)
24cd51
-        m_bInDigestValue = false;
24cd51
-    else if (rName == "SignatureValue")
24cd51
-    {
24cd51
-        m_pXSecController->setSignatureValue(m_aSignatureValue);
24cd51
-        m_bInSignatureValue = false;
24cd51
-    }
24cd51
-    else if (rName == "X509Data")
24cd51
-    {
24cd51
-        std::vector<std::pair<OUString, OUString>> X509IssuerSerials;
24cd51
-        std::vector<OUString> X509Certificates;
24cd51
-        if (!m_aX509Certificate.isEmpty())
24cd51
-        {
24cd51
-            X509Certificates.emplace_back(m_aX509Certificate);
24cd51
-        }
24cd51
-        if (!m_aX509IssuerName.isEmpty() && !m_aX509SerialNumber.isEmpty())
24cd51
-        {
24cd51
-            X509IssuerSerials.emplace_back(m_aX509IssuerName, m_aX509SerialNumber);
24cd51
-        }
24cd51
-        m_pXSecController->setX509Data(X509IssuerSerials, X509Certificates);
24cd51
-    }
24cd51
-    else if (rName == "X509Certificate")
24cd51
-    {
24cd51
-        m_bInX509Certificate = false;
24cd51
-    }
24cd51
-    else if (rName == "mdssi:Value")
24cd51
-    {
24cd51
-        m_pXSecController->setDate("", m_aMdssiValue);
24cd51
-        m_bInMdssiValue = false;
24cd51
-    }
24cd51
-    else if (rName == "SignatureComments")
24cd51
-    {
24cd51
-        m_pXSecController->setDescription("", m_aSignatureComments);
24cd51
-        m_bInSignatureComments = false;
24cd51
-    }
24cd51
-    else if (rName == "X509IssuerName")
24cd51
-    {
24cd51
-        m_bInX509IssuerName = false;
24cd51
-    }
24cd51
-    else if (rName == "X509SerialNumber")
24cd51
-    {
24cd51
-        m_bInX509SerialNumber = false;
24cd51
-    }
24cd51
-    else if (rName == "xd:Cert")
24cd51
-    {
24cd51
-        m_pXSecController->setX509CertDigest(m_aCertDigest, css::xml::crypto::DigestID::SHA1, m_aX509IssuerName, m_aX509SerialNumber);
24cd51
-    }
24cd51
-    else if (rName == "xd:CertDigest")
24cd51
-    {
24cd51
-        m_bInCertDigest = false;
24cd51
-    }
24cd51
-    else if (rName == "Object")
24cd51
+    assert(!m_ContextStack.empty()); // this should be checked by sax parser?
24cd51
+
24cd51
+    m_ContextStack.top()->EndElement();
24cd51
+
24cd51
+    if (m_xNextHandler.is())
24cd51
     {
24cd51
-        if (m_bInValidSignatureImage)
24cd51
-        {
24cd51
-            m_pXSecController->setValidSignatureImage(m_aValidSignatureImage);
24cd51
-            m_bInValidSignatureImage = false;
24cd51
-        }
24cd51
-        else if (m_bInInvalidSignatureImage)
24cd51
-        {
24cd51
-            m_pXSecController->setInvalidSignatureImage(m_aInvalidSignatureImage);
24cd51
-            m_bInInvalidSignatureImage = false;
24cd51
-        }
24cd51
+        m_xNextHandler->endElement(rName);
24cd51
     }
24cd51
-    else if (rName == "SetupID")
24cd51
+
24cd51
+    if (m_ContextStack.top()->m_pOldNamespaceMap)
24cd51
     {
24cd51
-        m_pXSecController->setSignatureLineId(m_aSignatureLineId);
24cd51
-        m_bInSignatureLineId = false;
24cd51
+        m_pNamespaceMap = std::move(m_ContextStack.top()->m_pOldNamespaceMap);
24cd51
     }
24cd51
-
24cd51
-    if (m_xNextHandler.is())
24cd51
-        m_xNextHandler->endElement(rName);
24cd51
+    m_ContextStack.pop();
24cd51
 }
24cd51
 
24cd51
 void SAL_CALL OOXMLSecParser::characters(const OUString& rChars)
24cd51
 {
24cd51
-    if (m_bInDigestValue && !m_bInCertDigest)
24cd51
-        m_aDigestValue += rChars;
24cd51
-    else if (m_bInSignatureValue)
24cd51
-        m_aSignatureValue += rChars;
24cd51
-    else if (m_bInX509Certificate)
24cd51
-        m_aX509Certificate += rChars;
24cd51
-    else if (m_bInMdssiValue)
24cd51
-        m_aMdssiValue += rChars;
24cd51
-    else if (m_bInSignatureComments)
24cd51
-        m_aSignatureComments += rChars;
24cd51
-    else if (m_bInX509IssuerName)
24cd51
-        m_aX509IssuerName += rChars;
24cd51
-    else if (m_bInX509SerialNumber)
24cd51
-        m_aX509SerialNumber += rChars;
24cd51
-    else if (m_bInCertDigest)
24cd51
-        m_aCertDigest += rChars;
24cd51
-    else if (m_bInValidSignatureImage)
24cd51
-        m_aValidSignatureImage += rChars;
24cd51
-    else if (m_bInInvalidSignatureImage)
24cd51
-        m_aInvalidSignatureImage += rChars;
24cd51
-    else if (m_bInSignatureLineId)
24cd51
-        m_aSignatureLineId += rChars;
24cd51
+    assert(!m_ContextStack.empty()); // this should be checked by sax parser?
24cd51
+    m_ContextStack.top()->Characters(rChars);
24cd51
 
24cd51
     if (m_xNextHandler.is())
24cd51
         m_xNextHandler->characters(rChars);
24cd51
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.hxx b/xmlsecurity/source/helper/ooxmlsecparser.hxx
be40d7
index d3c199147255..21ff01ff26da 100644
24cd51
--- a/xmlsecurity/source/helper/ooxmlsecparser.hxx
24cd51
+++ b/xmlsecurity/source/helper/ooxmlsecparser.hxx
24cd51
@@ -15,6 +15,10 @@
24cd51
 
24cd51
 #include <cppuhelper/implbase.hxx>
24cd51
 
24cd51
+#include <xmloff/nmspmap.hxx>
24cd51
+
24cd51
+#include <stack>
24cd51
+
24cd51
 class XSecController;
24cd51
 class XMLSignatureHelper;
24cd51
 
be40d7
@@ -25,38 +29,58 @@ class OOXMLSecParser: public cppu::WeakImplHelper
24cd51
     css::lang::XInitialization
24cd51
     >
24cd51
 {
24cd51
+public:
24cd51
+    class Context;
24cd51
+private:
24cd51
+    class UnknownContext;
24cd51
+    class ReferencedContextImpl;
24cd51
+    class DsX509CertificateContext;
24cd51
+    class DsX509SerialNumberContext;
24cd51
+    class DsX509IssuerNameContext;
24cd51
+    class DsX509IssuerSerialContext;
24cd51
+    class DsX509DataContext;
24cd51
+    class DsKeyInfoContext;
24cd51
+    class DsSignatureValueContext;
24cd51
+    class DsDigestValueContext;
24cd51
+    class DsDigestMethodContext;
24cd51
+    class DsTransformContext;
24cd51
+    class DsTransformsContext;
24cd51
+    class DsReferenceContext;
24cd51
+    class DsSignatureMethodContext;
24cd51
+    class DsSignedInfoContext;
24cd51
+    class XadesEncapsulatedX509CertificateContext;
24cd51
+    class XadesCertificateValuesContext;
24cd51
+    class XadesUnsignedSignaturePropertiesContext;
24cd51
+    class XadesUnsignedPropertiesContext;
24cd51
+    class XadesCertDigestContext;
24cd51
+    class XadesCertContext;
24cd51
+    class XadesSigningCertificateContext;
24cd51
+    class XadesSigningTimeContext;
24cd51
+    class XadesSignedSignaturePropertiesContext;
24cd51
+    class XadesSignedPropertiesContext;
24cd51
+    class XadesQualifyingPropertiesContext;
24cd51
+    class MdssiValueContext;
24cd51
+    class MdssiSignatureTimeContext;
24cd51
+    class MsodigsigSetupIDContext;
24cd51
+    class MsodigsigSignatureCommentsContext;
24cd51
+    class MsodigsigSignatureInfoV1Context;
24cd51
+    class DsSignaturePropertyContext;
24cd51
+    class DsSignaturePropertiesContext;
24cd51
+    class DsManifestContext;
24cd51
+    class DsObjectContext;
24cd51
+    class DsSignatureContext;
24cd51
+    class DsigSignaturesContext;
24cd51
+
24cd51
+    std::stack<std::unique_ptr<Context>> m_ContextStack;
24cd51
+    std::unique_ptr<SvXMLNamespaceMap> m_pNamespaceMap;
24cd51
+
24cd51
     XSecController* m_pXSecController;
24cd51
     css::uno::Reference<css::xml::sax::XDocumentHandler> m_xNextHandler;
24cd51
 
24cd51
-    bool m_bInDigestValue;
24cd51
-    OUString m_aDigestValue;
24cd51
-    bool m_bInSignatureValue;
24cd51
-    OUString m_aSignatureValue;
24cd51
-    bool m_bInX509Certificate;
24cd51
-    OUString m_aX509Certificate;
24cd51
-    bool m_bInMdssiValue;
24cd51
-    OUString m_aMdssiValue;
24cd51
-    bool m_bInSignatureComments;
24cd51
-    OUString m_aSignatureComments;
24cd51
-    bool m_bInX509IssuerName;
24cd51
-    OUString m_aX509IssuerName;
24cd51
-    bool m_bInX509SerialNumber;
24cd51
-    OUString m_aX509SerialNumber;
24cd51
-    bool m_bInCertDigest;
24cd51
-    OUString m_aCertDigest;
24cd51
-    bool m_bInValidSignatureImage;
24cd51
-    OUString m_aValidSignatureImage;
24cd51
-    bool m_bInInvalidSignatureImage;
24cd51
-    OUString m_aInvalidSignatureImage;
24cd51
-    bool m_bInSignatureLineId;
24cd51
-    OUString m_aSignatureLineId;
24cd51
-
be40d7
-    /// Last seen <Reference URI="...">.
be40d7
-    OUString m_aReferenceURI;
be40d7
-    /// Already called addStreamReference() for this reference.
be40d7
-    bool m_bReferenceUnresolved;
24cd51
     XMLSignatureHelper& m_rXMLSignatureHelper;
24cd51
 
24cd51
+    OUString HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs);
24cd51
+
24cd51
 public:
24cd51
     explicit OOXMLSecParser(XMLSignatureHelper& rXMLSignatureHelper, XSecController* pXSecController);
24cd51
     virtual ~OOXMLSecParser() override;
24cd51
-- 
be40d7
2.33.1
24cd51