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

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