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