Blame SOURCES/0003-xmlsecurity-replace-XSecParser-implementation.patch

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