include/xmloff/xmlimp.hxx                |    6 
 include/xmloff/xmlnamespace.hxx          |    7 
 include/xmloff/xmltoken.hxx              |   13 
 xmloff/source/core/xmlimp.cxx            |   23 
 xmloff/source/core/xmltoken.cxx          |   13 
 xmloff/source/token/tokens.txt           |   10 
 xmlsecurity/source/helper/xsecparser.cxx | 1630 ++++++++++++++++++++++++-------
 xmlsecurity/source/helper/xsecparser.hxx |   71 -
 8 files changed, 1426 insertions(+), 347 deletions(-)

New commits:
commit 12b15be8f4f930a04d8056b9219ac969b42a9784
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Feb 12 16:42:51 2021 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Mar 3 12:43:36 2021 +0100

    xmlsecurity: replace XSecParser implementation
    
    Implement Namespaces in XML and follow xmldsig-core and XAdES schemas.
    
    Change-Id: I03537b51bb757ecbfa63a826b38de543c70ba032
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110833
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx
index 2d5013e2fe4f..12a81a32888f 100644
--- a/include/xmloff/xmlimp.hxx
+++ b/include/xmloff/xmlimp.hxx
@@ -239,8 +239,12 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public 
cppu::WeakImplHelper<
 
     static void initializeNamespaceMaps();
     void registerNamespaces();
-    std::unique_ptr<SvXMLNamespaceMap> processNSAttributes(
+public:
+    static std::unique_ptr<SvXMLNamespaceMap> processNSAttributes(
+        std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap,
+        SvXMLImport *const pImport,
         const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList);
+private:
 
     css::uno::Reference< css::task::XStatusIndicator > mxStatusIndicator;
 
diff --git a/include/xmloff/xmlnamespace.hxx b/include/xmloff/xmlnamespace.hxx
index d45832f02d81..cabdcc7578e2 100644
--- a/include/xmloff/xmlnamespace.hxx
+++ b/include/xmloff/xmlnamespace.hxx
@@ -69,6 +69,13 @@ constexpr sal_uInt16 XML_NAMESPACE_TCD =             34;   
// text conversion di
 constexpr sal_uInt16 XML_NAMESPACE_DLG =             35;
 constexpr sal_uInt16 XML_NAMESPACE_REPORT =          36;
 constexpr sal_uInt16 XML_NAMESPACE_VERSIONS_LIST =   37;
+// OOo extension digital signatures, used in ODF 1.1
+constexpr sal_uInt16 XML_NAMESPACE_DSIG_OOO =        38;
+// ODF 1.2 digital signature namespaces
+constexpr sal_uInt16 XML_NAMESPACE_DSIG =            39;
+constexpr sal_uInt16 XML_NAMESPACE_DS =              40;
+constexpr sal_uInt16 XML_NAMESPACE_XADES132 =        41;
+constexpr sal_uInt16 XML_NAMESPACE_XADES141 =        42;
 
 // namespaces for ODF extended formats
 constexpr sal_uInt16 XML_NAMESPACE_EXT_BASE   = 50;
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index bc18f6230293..12a0632a5af7 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -135,6 +135,19 @@ namespace xmloff::token {
         XML_NP_GRDDL,
         XML_N_GRDDL,
 
+        // OOo extension digital signatures, used in ODF 1.1
+        XML_NP_DSIG_OOO,
+        XML_N_DSIG_OOO,
+        // ODF 1.2 digital signatures
+        XML_NP_DSIG,
+        XML_N_DSIG,
+        XML_NP_DS,
+        XML_N_DS,
+        XML_NP_XADES132,
+        XML_N_XADES132,
+        XML_NP_XADES141,
+        XML_N_XADES141,
+
         // ODF Enhanced namespaces
         XML_NP_OFFICE_EXT,
         XML_N_OFFICE_EXT,
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index 8c4b02f50754..6d7b0805ddfb 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -671,6 +671,8 @@ void SAL_CALL SvXMLImport::endDocument()
 }
 
 std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
+        std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap,
+        SvXMLImport *const pImport, // TODO???
         const uno::Reference< xml::sax::XAttributeList >& xAttrList)
 {
     std::unique_ptr<SvXMLNamespaceMap> pRewindMap;
@@ -678,12 +680,13 @@ std::unique_ptr<SvXMLNamespaceMap> 
SvXMLImport::processNSAttributes(
     for( sal_Int16 i=0; i < nAttrCount; i++ )
     {
         const OUString& rAttrName = xAttrList->getNameByIndex( i );
-        if ( rAttrName == "office:version" && !mpImpl->mxODFVersion )
+        if (pImport && rAttrName == "office:version" && 
!pImport->mpImpl->mxODFVersion)
         {
-            mpImpl->mxODFVersion = xAttrList->getValueByIndex( i );
+            pImport->mpImpl->mxODFVersion = xAttrList->getValueByIndex( i );
 
             // the ODF version in content.xml and manifest.xml must be the 
same starting from ODF1.2
-            if ( mpImpl->mStreamName == "content.xml" && 
!IsODFVersionConsistent( *mpImpl->mxODFVersion ) )
+            if (pImport->mpImpl->mStreamName == "content.xml"
+                && 
!pImport->IsODFVersionConsistent(*pImport->mpImpl->mxODFVersion))
             {
                 throw xml::sax::SAXException("Inconsistent ODF versions in 
content.xml and manifest.xml!",
                         uno::Reference< uno::XInterface >(),
@@ -697,8 +700,8 @@ std::unique_ptr<SvXMLNamespaceMap> 
SvXMLImport::processNSAttributes(
         {
             if( !pRewindMap )
             {
-                pRewindMap = std::move(mpNamespaceMap);
-                mpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap));
+                pRewindMap = std::move(rpNamespaceMap);
+                rpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap));
             }
             const OUString& rAttrValue = xAttrList->getValueByIndex( i );
 
@@ -706,18 +709,18 @@ std::unique_ptr<SvXMLNamespaceMap> 
SvXMLImport::processNSAttributes(
                                  ? OUString()
                                  : rAttrName.copy( 6 ) );
             // Add namespace, but only if it is known.
-            sal_uInt16 nKey = mpNamespaceMap->AddIfKnown( aPrefix, rAttrValue 
);
+            sal_uInt16 nKey = rpNamespaceMap->AddIfKnown( aPrefix, rAttrValue 
);
             // If namespace is unknown, try to match a name with similar
             // TC Id and version
             if( XML_NAMESPACE_UNKNOWN == nKey  )
             {
                 OUString aTestName( rAttrValue );
                 if( SvXMLNamespaceMap::NormalizeURI( aTestName ) )
-                    nKey = mpNamespaceMap->AddIfKnown( aPrefix, aTestName );
+                    nKey = rpNamespaceMap->AddIfKnown( aPrefix, aTestName );
             }
             // If that namespace is not known, too, add it as unknown
             if( XML_NAMESPACE_UNKNOWN == nKey  )
-                mpNamespaceMap->Add( aPrefix, rAttrValue );
+                rpNamespaceMap->Add( aPrefix, rAttrValue );
 
         }
     }
@@ -768,7 +771,7 @@ void SAL_CALL SvXMLImport::startFastElement (sal_Int32 
Element,
     maNamespaceAttrList->Clear();
 
     maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList );
-    std::unique_ptr<SvXMLNamespaceMap> pRewindMap = processNSAttributes( 
maNamespaceAttrList );
+    std::unique_ptr<SvXMLNamespaceMap> pRewindMap = 
processNSAttributes(mpNamespaceMap, this, maNamespaceAttrList);
 
     SvXMLImportContextRef xContext;
     const bool bRootContext = maContexts.empty();
@@ -2148,7 +2151,7 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( 
const OUString& rName,
     sal_uInt16 nDefaultNamespace = XML_NAMESPACE_UNKNOWN;
     if (!maDefaultNamespaces.empty())
         nDefaultNamespace = maDefaultNamespaces.top();
-    mrImport->processNSAttributes(xAttrList);
+    SvXMLImport::processNSAttributes(mrImport->mpNamespaceMap, mrImport.get(), 
xAttrList);
     OUString aLocalName;
     sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, 
&aLocalName );
     sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | 
SvXMLImport::getTokenFromName( aLocalName );
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 6264eda43b31..0a2f9104d0a7 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -144,6 +144,19 @@ namespace xmloff::token {
         TOKEN( "grddl",                                 XML_NP_GRDDL ),
         TOKEN( "http://www.w3.org/2003/g/data-view#";,   XML_N_GRDDL ),
 
+        // OOo extension digital signatures, used in ODF 1.1
+        TOKEN( "dsigooo", XML_NP_DSIG_OOO ),
+        TOKEN( "http://openoffice.org/2004/documentsignatures";, XML_N_DSIG_OOO 
),
+        // ODF 1.2 digital signature namespaces
+        TOKEN( "dsig", XML_NP_DSIG ),
+        TOKEN( "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0", 
XML_N_DSIG ),
+        TOKEN( "ds", XML_NP_DS ),
+        TOKEN( "http://www.w3.org/2000/09/xmldsig#";, XML_N_DS ),
+        TOKEN( "xades132", XML_NP_XADES132 ),
+        TOKEN( "http://uri.etsi.org/01903/v1.3.2#";, XML_N_XADES132 ),
+        TOKEN( "xades141", XML_NP_XADES141 ),
+        TOKEN( "http://uri.etsi.org/01903/v1.4.1#";, XML_N_XADES141 ),
+
         // ODF Enhanced namespaces
         TOKEN( "officeooo", XML_NP_OFFICE_EXT ),
         TOKEN( "http://openoffice.org/2009/office";, XML_N_OFFICE_EXT ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 503fadc0cca9..10af0324fee6 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -72,6 +72,16 @@ xhtml
 N_XHTML_DUMMY
 grddl
 N_GRDDL_DUMMY
+dsigooo
+N_DSIG_OOO_DUMMY
+dsig
+N_DSIG_DUMMY
+ds
+N_DS_DUMMY
+xades132
+N_XADES132_DUMMY
+xades141
+N_XADES141_DUMMY
 officeooo
 N_OFFICE_EXT_DUMMY
 formx
diff --git a/xmlsecurity/source/helper/xsecparser.cxx 
b/xmlsecurity/source/helper/xsecparser.cxx
index 9f2bbe074a1b..1f2045c5d0e3 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -21,476 +21,1474 @@
 #include "xsecparser.hxx"
 #include <xsecctl.hxx>
 #include <xmlsignaturehelper.hxx>
+
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlimp.hxx>
+
 #include <com/sun/star/xml/sax/SAXException.hpp>
 #include <cppuhelper/exc_hlp.hxx>
 #include <sal/log.hxx>
 
+class XSecParser::Context
+{
+    protected:
+        friend class XSecParser;
+        XSecParser & m_rParser;
+    private:
+        std::unique_ptr<SvXMLNamespaceMap> m_pOldNamespaceMap;
 
-XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper,
-    XSecController* pXSecController)
-    : m_bInX509IssuerName(false)
-    , m_bInX509SerialNumber(false)
-    , m_bInX509Certificate(false)
-    , m_bInGpgCertificate(false)
-    , m_bInGpgKeyID(false)
-    , m_bInGpgOwner(false)
-    , m_bInCertDigest(false)
-    , m_bInEncapsulatedX509Certificate(false)
-    , m_bInSigningTime(false)
-    , m_bInDigestValue(false)
-    , m_bInSignatureValue(false)
-    , m_bInDate(false)
-    , m_bInDescription(false)
-    , m_bInSignatureLineId(false)
-    , m_bInSignatureLineValidImage(false)
-    , m_bInSignatureLineInvalidImage(false)
-    , m_pXSecController(pXSecController)
-    , m_bReferenceUnresolved(false)
-    , m_nReferenceDigestID(css::xml::crypto::DigestID::SHA1)
-    , m_rXMLSignatureHelper(rXMLSignatureHelper)
+    public:
+        Context(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : m_rParser(rParser)
+            , m_pOldNamespaceMap(std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual ~Context() = default;
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/)
+        {
+        }
+
+        virtual void EndElement()
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/);
+
+        virtual void Characters(OUString const& /*rChars*/)
+        {
+        }
+};
+
+// it's possible that an unsupported element has an Id attribute and a
+// ds:Reference digesting it - probably this means XSecController needs to know
+// about it. (For known elements, the Id attribute is only processed according
+// to the schema.)
+class XSecParser::UnknownContext
+    : public XSecParser::Context
+{
+    public:
+        UnknownContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+};
+
+auto XSecParser::Context::CreateChildContext(
+    std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+    sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/)
+-> std::unique_ptr<Context>
 {
+    // default: create new base context
+    return std::make_unique<UnknownContext>(m_rParser, 
std::move(pOldNamespaceMap));
 }
 
-OUString XSecParser::getIdAttr(const css::uno::Reference< 
css::xml::sax::XAttributeList >& xAttribs )
+class XSecParser::LoPGPOwnerContext
+    : public XSecParser::Context
 {
-    OUString ouIdAttr = xAttribs->getValueByName("id");
+    public:
+        LoPGPOwnerContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
 
-    if (ouIdAttr.isEmpty())
-    {
-        ouIdAttr = xAttribs->getValueByName("Id");
-    }
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouGpgOwner.clear();
+        }
 
-    return ouIdAttr;
-}
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setGpgOwner( m_rParser.m_ouGpgOwner );
+        }
 
-/*
- * XDocumentHandler
- */
-void SAL_CALL XSecParser::startDocument(  )
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouGpgOwner += rChars;
+        }
+};
+
+class XSecParser::DsPGPKeyPacketContext
+    : public XSecParser::Context
 {
-    m_bInX509IssuerName = false;
-    m_bInX509SerialNumber = false;
-    m_bInX509Certificate = false;
-    m_bInGpgCertificate = false;
-    m_bInGpgKeyID = false;
-    m_bInGpgOwner = false;
-    m_bInSignatureValue = false;
-    m_bInDigestValue = false;
-    m_bInDate = false;
-    m_bInDescription = false;
+    public:
+        DsPGPKeyPacketContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
 
-    if (m_xNextHandler.is())
-    {
-        m_xNextHandler->startDocument();
-    }
-}
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouGpgCertificate.clear();
+        }
 
-void SAL_CALL XSecParser::endDocument(  )
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setGpgCertificate( 
m_rParser.m_ouGpgCertificate );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouGpgCertificate += rChars;
+        }
+};
+
+class XSecParser::DsPGPKeyIDContext
+    : public XSecParser::Context
 {
-    if (m_xNextHandler.is())
-    {
-        m_xNextHandler->endDocument();
-    }
-}
+    public:
+        DsPGPKeyIDContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
 
-void SAL_CALL XSecParser::startElement(
-    const OUString& aName,
-    const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouGpgKeyID.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setGpgKeyID( m_rParser.m_ouGpgKeyID );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouGpgKeyID += rChars;
+        }
+};
+
+class XSecParser::DsPGPDataContext
+    : public XSecParser::Context
 {
-    try
-    {
-        OUString ouIdAttr = getIdAttr(xAttribs);
-        if (!ouIdAttr.isEmpty())
+    public:
+        DsPGPDataContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_pXSecController->collectToVerify( ouIdAttr );
         }
 
-        if ( aName == "Signature" )
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
         {
-            m_rXMLSignatureHelper.StartVerifySignatureElement();
-            m_pXSecController->addSignature();
-            if (!ouIdAttr.isEmpty())
+            m_rParser.m_pXSecController->switchGpgSignature();
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "PGPKeyID")
             {
-                m_pXSecController->setId( ouIdAttr );
+                return std::make_unique<DsPGPKeyIDContext>(m_rParser, 
std::move(pOldNamespaceMap));
             }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "PGPKeyPacket")
+            {
+                return std::make_unique<DsPGPKeyPacketContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "PGPOwner")
+            {
+                return std::make_unique<LoPGPOwnerContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "SignatureMethod")
+};
+
+class XSecParser::DsX509CertificateContext
+    : public XSecParser::Context
+{
+    public:
+        DsX509CertificateContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouX509Certificate.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setX509Certificate( 
m_rParser.m_ouX509Certificate );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouX509Certificate += rChars;
+        }
+};
+
+class XSecParser::DsX509SerialNumberContext
+    : public XSecParser::Context
+{
+    public:
+        DsX509SerialNumberContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouX509SerialNumber.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setX509SerialNumber( 
m_rParser.m_ouX509SerialNumber );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouX509SerialNumber += rChars;
+        }
+};
+
+class XSecParser::DsX509IssuerNameContext
+    : public XSecParser::Context
+{
+    public:
+        DsX509IssuerNameContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouX509IssuerName.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setX509IssuerName( 
m_rParser.m_ouX509IssuerName );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouX509IssuerName += rChars;
+        }
+};
+
+class XSecParser::DsX509IssuerSerialContext
+    : public XSecParser::Context
+{
+    public:
+        DsX509IssuerSerialContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerName")
+            {
+                return std::make_unique<DsX509IssuerNameContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509SerialNumber")
+            {
+                return std::make_unique<DsX509SerialNumberContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::DsX509DataContext
+    : public XSecParser::Context
+{
+    public:
+        DsX509DataContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerSerial")
+            {
+                return std::make_unique<DsX509IssuerSerialContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509Certificate")
+            {
+                return std::make_unique<DsX509CertificateContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::DsKeyInfoContext
+    : public XSecParser::Context
+{
+    public:
+        DsKeyInfoContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509Data")
+            {
+                return std::make_unique<DsX509DataContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "PGPData")
+            {
+                return std::make_unique<DsPGPDataContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing: ds:KeyName, ds:KeyValue, ds:RetrievalMethod, 
ds:SPKIData, ds:MgmtData
+            // (old code would read ds:Transform inside ds:RetrievalMethod but
+            // presumably that was a bug)
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+
+};
+
+class XSecParser::DsSignatureValueContext
+    : public XSecParser::Context
+{
+    public:
+        DsSignatureValueContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+            m_rParser.m_ouSignatureValue.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setSignatureValue( 
m_rParser.m_ouSignatureValue );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouSignatureValue += rChars;
+        }
+};
+
+class XSecParser::DsDigestValueContext
+    : public XSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        DsDigestValueContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rValue.clear();
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class XSecParser::DsDigestMethodContext
+    : public XSecParser::Context
+{
+    public:
+        DsDigestMethodContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+
+            SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no 
Algorithm in Reference" );
+            if (!ouAlgorithm.isEmpty())
+            {
+                SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1
+                             && ouAlgorithm != ALGO_XMLDSIGSHA256
+                             && ouAlgorithm != ALGO_XMLDSIGSHA512,
+                             "xmlsecurity.helper", "Algorithm neither SHA1, 
SHA256 nor SHA512");
+                if (ouAlgorithm == ALGO_XMLDSIGSHA1)
+                    m_rParser.m_nReferenceDigestID = 
css::xml::crypto::DigestID::SHA1;
+                else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
+                    m_rParser.m_nReferenceDigestID = 
css::xml::crypto::DigestID::SHA256;
+                else if (ouAlgorithm == ALGO_XMLDSIGSHA512)
+                    m_rParser.m_nReferenceDigestID = 
css::xml::crypto::DigestID::SHA512;
+                else
+                    m_rParser.m_nReferenceDigestID = 0;
+            }
+        }
+};
+
+class XSecParser::DsTransformContext
+    : public XSecParser::Context
+{
+    public:
+        DsTransformContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            if (m_rParser.m_bReferenceUnresolved)
+            {
+                OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+
+                if (ouAlgorithm == ALGO_C14N)
+                    /*
+                     * a xml stream
+                     */
+                {
+                    m_rParser.m_pXSecController->addStreamReference( 
m_rParser.m_currentReferenceURI, false, m_rParser.m_nReferenceDigestID );
+                    m_rParser.m_bReferenceUnresolved = false;
+                }
+            }
+        }
+};
+
+class XSecParser::DsTransformsContext
+    : public XSecParser::Context
+{
+    public:
+        DsTransformsContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Transform")
+            {
+                return std::make_unique<DsTransformContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::DsReferenceContext
+    : public XSecParser::Context
+{
+    public:
+        DsReferenceContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+
+            OUString ouUri = xAttrs->getValueByName("URI");
+            SAL_WARN_IF( ouUri.isEmpty(), "xmlsecurity.helper", "URI is empty" 
);
+            // Remember the type of this reference.
+            OUString ouType = xAttrs->getValueByName("Type");
+            if (ouUri.startsWith("#"))
+            {
+                /*
+                * remove the first character '#' from the attribute value
+                */
+                m_rParser.m_pXSecController->addReference( ouUri.copy(1), 
m_rParser.m_nReferenceDigestID, ouType );
+            }
+            else
+            {
+                /*
+                * remember the uri
+                */
+                m_rParser.m_currentReferenceURI = ouUri;
+                m_rParser.m_bReferenceUnresolved = true;
+            }
+        }
+
+        virtual void EndElement() override
+        {
+            if (m_rParser.m_bReferenceUnresolved)
+            /*
+            * it must be an octet stream
+            */
+            {
+                m_rParser.m_pXSecController->addStreamReference( 
m_rParser.m_currentReferenceURI, true, m_rParser.m_nReferenceDigestID );
+                m_rParser.m_bReferenceUnresolved = false;
+            }
+
+            m_rParser.m_pXSecController->setDigestValue( 
m_rParser.m_nReferenceDigestID, m_rParser.m_ouDigestValue );
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Transforms")
+            {
+                return std::make_unique<DsTransformsContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
+            {
+                return std::make_unique<DsDigestMethodContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
+            {
+                return std::make_unique<DsDigestValueContext>(m_rParser, 
std::move(pOldNamespaceMap), m_rParser.m_ouDigestValue);
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::DsSignatureMethodContext
+    : public XSecParser::Context
+{
+    public:
+        DsSignatureMethodContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
             if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == 
ALGO_ECDSASHA256
                 || ouAlgorithm == ALGO_ECDSASHA512)
-                
m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
+            {
+                
m_rParser.m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
+            }
+        }
+};
+
+class XSecParser::DsSignedInfoContext
+    : public XSecParser::Context
+{
+    public:
+        DsSignedInfoContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setReferenceCount();
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureMethod")
+            {
+                return std::make_unique<DsSignatureMethodContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
+            {
+                return std::make_unique<DsReferenceContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing: ds:CanonicalizationMethod
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::XadesEncapsulatedX509CertificateContext
+    : public XSecParser::Context
+{
+    public:
+        XadesEncapsulatedX509CertificateContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+            m_rParser.m_ouEncapsulatedX509Certificate.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->addEncapsulatedX509Certificate( 
m_rParser.m_ouEncapsulatedX509Certificate );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouEncapsulatedX509Certificate += rChars;
+        }
+};
+
+class XSecParser::XadesCertificateValuesContext
+    : public XSecParser::Context
+{
+    public:
+        XadesCertificateValuesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"EncapsulatedX509Certificate")
+            {
+                return 
std::make_unique<XadesEncapsulatedX509CertificateContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing: xades:OtherCertificate
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::XadesUnsignedSignaturePropertiesContext
+    : public XSecParser::Context
+{
+    public:
+        XadesUnsignedSignaturePropertiesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
         }
-        else if ( aName == "Reference" )
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"CertificateValues")
+            {
+                return 
std::make_unique<XadesCertificateValuesContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing:
+            // xades:CounterSignature
+            //  ^ old code would read a ds:Signature inside it?
+            // xades:SignatureTimeStamp
+            // xades:CompleteCertificateRefs
+            // xades:CompleteRevocationRefs
+            // xades:AttributeCertificateRefs
+            // xades:AttributeRevocationRefs
+            // xades:SigAndRefsTimeStamp
+            // xades:RefsOnlyTimeStamp
+            // xades:RevocationValues
+            // xades:AttrAuthoritiesCertValues
+            //  ^ old code: was equivalent to CertificateValues ???
+            // xades:AttributeRevocationValues
+            // xades:ArchiveTimeStamp
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::XadesUnsignedPropertiesContext
+    : public XSecParser::Context
+{
+    public:
+        XadesUnsignedPropertiesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"UnsignedSignatureProperties")
+            {
+                return 
std::make_unique<XadesUnsignedSignaturePropertiesContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing: xades:UnsignedDataObjectProperties
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::LoSignatureLineIdContext
+    : public XSecParser::Context
+{
+    public:
+        LoSignatureLineIdContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouSignatureLineId.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setSignatureLineId( 
m_rParser.m_ouSignatureLineId );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouSignatureLineId += rChars;
+        }
+};
+
+class XSecParser::LoSignatureLineValidImageContext
+    : public XSecParser::Context
+{
+    public:
+        LoSignatureLineValidImageContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouSignatureLineValidImage.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setValidSignatureImage( 
m_rParser.m_ouSignatureLineValidImage );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouSignatureLineValidImage += rChars;
+        }
+};
+
+class XSecParser::LoSignatureLineInvalidImageContext
+    : public XSecParser::Context
+{
+    public:
+        LoSignatureLineInvalidImageContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
+        {
+            m_rParser.m_ouSignatureLineInvalidImage.clear();
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setInvalidSignatureImage( 
m_rParser.m_ouSignatureLineInvalidImage );
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rParser.m_ouSignatureLineInvalidImage += rChars;
+        }
+};
+
+class XSecParser::LoSignatureLineContext
+    : public XSecParser::Context
+{
+    public:
+        LoSignatureLineContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_LO_EXT && rName == 
"SignatureLineId")
+            {
+                return std::make_unique<LoSignatureLineIdContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_LO_EXT && rName == 
"SignatureLineValidImage")
+            {
+                return 
std::make_unique<LoSignatureLineValidImageContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_LO_EXT && rName == 
"SignatureLineInvalidImage")
+            {
+                return 
std::make_unique<LoSignatureLineInvalidImageContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
+        }
+};
+
+class XSecParser::XadesCertDigestContext
+    : public XSecParser::Context
+{
+    public:
+        XadesCertDigestContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setCertDigest( 
m_rParser.m_ouCertDigest );
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            OUString ouUri = xAttribs->getValueByName("URI");
-            SAL_WARN_IF( ouUri.isEmpty(), "xmlsecurity.helper", "URI is empty" 
);
-            // Remember the type of this reference.
-            OUString ouType = xAttribs->getValueByName("Type");
-            if (ouUri.startsWith("#"))
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
             {
-                /*
-                * remove the first character '#' from the attribute value
-                */
-                m_pXSecController->addReference( ouUri.copy(1), 
m_nReferenceDigestID, ouType );
+                return std::make_unique<DsDigestMethodContext>(m_rParser, 
std::move(pOldNamespaceMap));
             }
-            else
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
             {
-                /*
-                * remember the uri
-                */
-                m_currentReferenceURI = ouUri;
-                m_bReferenceUnresolved = true;
+                return std::make_unique<DsDigestValueContext>(m_rParser, 
std::move(pOldNamespaceMap), m_rParser.m_ouCertDigest);
             }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "DigestMethod")
+};
+
+class XSecParser::XadesCertContext
+    : public XSecParser::Context
+{
+    public:
+        XadesCertContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
+        }
 
-            SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no 
Algorithm in Reference" );
-            if (!ouAlgorithm.isEmpty())
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertDigest")
             {
-                SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1
-                             && ouAlgorithm != ALGO_XMLDSIGSHA256
-                             && ouAlgorithm != ALGO_XMLDSIGSHA512,
-                             "xmlsecurity.helper", "Algorithm neither SHA1, 
SHA256 nor SHA512");
-                if (ouAlgorithm == ALGO_XMLDSIGSHA1)
-                    m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1;
-                else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
-                    m_nReferenceDigestID = css::xml::crypto::DigestID::SHA256;
-                else if (ouAlgorithm == ALGO_XMLDSIGSHA512)
-                    m_nReferenceDigestID = css::xml::crypto::DigestID::SHA512;
-                else
-                    m_nReferenceDigestID = 0;
+                return std::make_unique<XadesCertDigestContext>(m_rParser, 
std::move(pOldNamespaceMap));
             }
-        }
-        else if (aName == "Transform")
-        {
-            if ( m_bReferenceUnresolved )
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"IssuerSerial")
             {
-                OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
-
-                if (ouAlgorithm == ALGO_C14N)
-                    /*
-                     * a xml stream
-                     */
-                {
-                    m_pXSecController->addStreamReference( 
m_currentReferenceURI, false, m_nReferenceDigestID );
-                    m_bReferenceUnresolved = false;
-                }
+                return std::make_unique<DsX509IssuerSerialContext>(m_rParser, 
std::move(pOldNamespaceMap));
             }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "X509IssuerName")
-        {
-            m_ouX509IssuerName.clear();
-            m_bInX509IssuerName = true;
-        }
-        else if (aName == "X509SerialNumber")
+};
+
+class XSecParser::XadesSigningCertificateContext
+    : public XSecParser::Context
+{
+    public:
+        XadesSigningCertificateContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_ouX509SerialNumber.clear();
-            m_bInX509SerialNumber = true;
         }
-        else if (aName == "X509Certificate")
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            m_ouX509Certificate.clear();
-            m_bInX509Certificate = true;
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "Cert")
+            {
+                return std::make_unique<XadesCertContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "PGPData")
+};
+
+class XSecParser::XadesSigningTimeContext
+    : public XSecParser::Context
+{
+    public:
+        XadesSigningTimeContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_pXSecController->switchGpgSignature();
         }
-        else if (aName == "PGPKeyID")
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
         {
-            m_ouGpgKeyID.clear();
-            m_bInGpgKeyID = true;
+            m_rParser.m_ouDate.clear();
         }
-        else if (aName == "PGPKeyPacket")
+
+        virtual void EndElement() override
         {
-            m_ouGpgCertificate.clear();
-            m_bInGpgCertificate = true;
+            m_rParser.m_pXSecController->setDate( m_rParser.m_ouDate );
         }
-        else if (aName == "loext:PGPOwner")
+
+        virtual void Characters(OUString const& rChars) override
         {
-            m_ouGpgOwner.clear();
-            m_bInGpgOwner = true;
+            m_rParser.m_ouDate += rChars;
         }
-        else if (aName == "SignatureValue")
+};
+
+class XSecParser::XadesSignedSignaturePropertiesContext
+    : public XSecParser::Context
+{
+    public:
+        XadesSignedSignaturePropertiesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_ouSignatureValue.clear();
-            m_bInSignatureValue = true;
         }
-        else if (aName == "DigestValue" && !m_bInCertDigest)
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
         {
-            m_ouDigestValue.clear();
-            m_bInDigestValue = true;
+            m_rParser.HandleIdAttr(xAttrs);
         }
-        else if (aName == "xd:CertDigest")
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            m_ouCertDigest.clear();
-            m_bInCertDigest = true;
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningTime")
+            {
+                return std::make_unique<XadesSigningTimeContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"SigningCertificate")
+            {
+                return 
std::make_unique<XadesSigningCertificateContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_LO_EXT && rName == "SignatureLine")
+            {
+                return std::make_unique<LoSignatureLineContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            // missing: xades:SignaturePolicyIdentifier, 
xades:SignatureProductionPlace, xades:SignerRole
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        // FIXME: Existing code here in xmlsecurity uses "xd" as the namespace 
prefix for XAdES,
-        // while the sample document attached to tdf#76142 uses "xades". So 
accept either here. Of
-        // course this is idiotic and wrong, the right thing would be to use a 
proper way to parse
-        // XML that would handle namespaces correctly. I have no idea how 
substantial re-plumbing of
-        // this code that would require.
-        else if (aName == "xd:EncapsulatedX509Certificate" || aName == 
"xades:EncapsulatedX509Certificate")
+};
+
+class XSecParser::XadesSignedPropertiesContext
+    : public XSecParser::Context
+{
+    public:
+        XadesSignedPropertiesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_ouEncapsulatedX509Certificate.clear();
-            m_bInEncapsulatedX509Certificate = true;
         }
-        else if (aName == "xd:SigningTime" || aName == "xades:SigningTime")
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
         {
-            m_ouDate.clear();
-            m_bInSigningTime = true;
+            m_rParser.HandleIdAttr(xAttrs);
         }
-        else if ( aName == "SignatureProperty" )
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            if (!ouIdAttr.isEmpty())
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"SignedSignatureProperties")
             {
-                m_pXSecController->setPropertyId( ouIdAttr );
+                return 
std::make_unique<XadesSignedSignaturePropertiesContext>(m_rParser, 
std::move(pOldNamespaceMap));
             }
+            // missing: xades:SignedDataObjectProperties
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "dc:date")
-        {
-            if (m_ouDate.isEmpty())
-                m_bInDate = true;
-        }
-        else if (aName == "dc:description")
+};
+
+class XSecParser::XadesQualifyingPropertiesContext
+    : public XSecParser::Context
+{
+    public:
+        XadesQualifyingPropertiesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_ouDescription.clear();
-            m_bInDescription = true;
         }
-        else if (aName == "loext:SignatureLineId")
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
         {
-            m_ouSignatureLineId.clear();
-            m_bInSignatureLineId = true;
+            m_rParser.HandleIdAttr(xAttrs);
         }
-        else if (aName == "loext:SignatureLineValidImage")
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            m_ouSignatureLineValidImage.clear();
-            m_bInSignatureLineValidImage = true;
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"SignedProperties")
+            {
+                return 
std::make_unique<XadesSignedPropertiesContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"UnsignedProperties")
+            {
+                return 
std::make_unique<XadesUnsignedPropertiesContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "loext:SignatureLineInvalidImage")
+};
+
+class XSecParser::DcDateContext
+    : public XSecParser::Context
+{
+    private:
+        bool m_isIgnore = false;
+
+    public:
+        DcDateContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_ouSignatureLineInvalidImage.clear();
-            m_bInSignatureLineInvalidImage = true;
         }
 
-        if (m_xNextHandler.is())
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
         {
-            m_xNextHandler->startElement(aName, xAttribs);
+            m_isIgnore = !m_rParser.m_ouDate.isEmpty();
         }
-    }
-    catch (css::uno::Exception& )
-    {//getCaughtException MUST be the first line in the catch block
-        css::uno::Any exc =  cppu::getCaughtException();
-        throw css::xml::sax::SAXException(
-            "xmlsecurity: Exception in XSecParser::startElement",
-            nullptr, exc);
-    }
-    catch (...)
-    {
-        throw css::xml::sax::SAXException(
-            "xmlsecurity: unexpected exception in XSecParser::startElement", 
nullptr,
-            css::uno::Any());
-    }
-}
 
-void SAL_CALL XSecParser::endElement( const OUString& aName )
-{
-    try
-    {
-        if (aName == "DigestValue" && !m_bInCertDigest)
+        virtual void EndElement() override
         {
-            m_bInDigestValue = false;
+            if (!m_isIgnore)
+            {
+                m_rParser.m_pXSecController->setDate( m_rParser.m_ouDate );
+            }
         }
-        else if ( aName == "Reference" )
+
+        virtual void Characters(OUString const& rChars) override
         {
-            if ( m_bReferenceUnresolved )
-            /*
-            * it must be an octet stream
-            */
+            if (!m_isIgnore)
             {
-                m_pXSecController->addStreamReference( m_currentReferenceURI, 
true, m_nReferenceDigestID );
-                m_bReferenceUnresolved = false;
+                m_rParser.m_ouDate += rChars;
             }
+        }
+};
 
-            m_pXSecController->setDigestValue( m_nReferenceDigestID, 
m_ouDigestValue );
+class XSecParser::DcDescriptionContext
+    : public XSecParser::Context
+{
+    public:
+        DcDescriptionContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
         }
-        else if ( aName == "SignedInfo" )
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& 
/*xAttrs*/) override
         {
-            m_pXSecController->setReferenceCount();
+            m_rParser.m_ouDescription.clear();
         }
-        else if ( aName == "SignatureValue" )
+
+        virtual void EndElement() override
         {
-            m_pXSecController->setSignatureValue( m_ouSignatureValue );
-            m_bInSignatureValue = false;
+            m_rParser.m_pXSecController->setDescription( 
m_rParser.m_ouDescription );
         }
-        else if (aName == "X509IssuerName")
+
+        virtual void Characters(OUString const& rChars) override
         {
-            m_pXSecController->setX509IssuerName( m_ouX509IssuerName );
-            m_bInX509IssuerName = false;
+            m_rParser.m_ouDescription += rChars;
         }
-        else if (aName == "X509SerialNumber")
+};
+
+class XSecParser::DsSignaturePropertyContext
+    : public XSecParser::Context
+{
+    public:
+        DsSignaturePropertyContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_pXSecController->setX509SerialNumber( m_ouX509SerialNumber );
-            m_bInX509SerialNumber = false;
         }
-        else if (aName == "X509Certificate")
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
         {
-            m_pXSecController->setX509Certificate( m_ouX509Certificate );
-            m_bInX509Certificate = false;
+            OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs));
+            if (!ouIdAttr.isEmpty())
+            {
+                m_rParser.m_pXSecController->setPropertyId( ouIdAttr );
+            }
         }
-        else if (aName == "PGPKeyID")
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            m_pXSecController->setGpgKeyID( m_ouGpgKeyID );
-            m_bInGpgKeyID = false;
+            if (nNamespace == XML_NAMESPACE_DC && rName == "date")
+            {
+                return std::make_unique<DcDateContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DC && rName == "description")
+            {
+                return std::make_unique<DcDescriptionContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "PGPKeyPacket")
+};
+
+class XSecParser::DsSignaturePropertiesContext
+    : public XSecParser::Context
+{
+    public:
+        DsSignaturePropertiesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_pXSecController->setGpgCertificate( m_ouGpgCertificate );
-            m_bInGpgCertificate = false;
         }
-        else if (aName == "loext:PGPOwner")
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
         {
-            m_pXSecController->setGpgOwner( m_ouGpgOwner );
-            m_bInGpgOwner = false;
+            m_rParser.HandleIdAttr(xAttrs);
         }
-        else if (aName == "xd:CertDigest")
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            m_pXSecController->setCertDigest( m_ouCertDigest );
-            m_bInCertDigest = false;
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperty")
+            {
+                return std::make_unique<DsSignaturePropertyContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "xd:EncapsulatedX509Certificate" || aName == 
"xades:EncapsulatedX509Certificate")
+};
+
+class XSecParser::DsObjectContext
+    : public XSecParser::Context
+{
+    public:
+        DsObjectContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_pXSecController->addEncapsulatedX509Certificate( 
m_ouEncapsulatedX509Certificate );
-            m_bInEncapsulatedX509Certificate = false;
         }
-        else if (aName == "xd:SigningTime" || aName == "xades:SigningTime")
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
         {
-            m_pXSecController->setDate( m_ouDate );
-            m_bInSigningTime = false;
+            m_rParser.HandleIdAttr(xAttrs);
         }
-        else if (aName == "dc:date")
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            if (m_bInDate)
+            if (nNamespace == XML_NAMESPACE_DS && rName == 
"SignatureProperties")
+            {
+                return 
std::make_unique<DsSignaturePropertiesContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == 
"QualifyingProperties")
             {
-                m_pXSecController->setDate( m_ouDate );
-                m_bInDate = false;
+                return 
std::make_unique<XadesQualifyingPropertiesContext>(m_rParser, 
std::move(pOldNamespaceMap));
             }
+            // missing: ds:Manifest
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "dc:description")
+};
+
+class XSecParser::DsSignatureContext
+    : public XSecParser::Context
+{
+    public:
+        DsSignatureContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_pXSecController->setDescription( m_ouDescription );
-            m_bInDescription = false;
         }
-        else if (aName == "loext:SignatureLineId")
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) 
override
         {
-            m_pXSecController->setSignatureLineId( m_ouSignatureLineId );
-            m_bInSignatureLineId = false;
+            OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs));
+            m_rParser.m_rXMLSignatureHelper.StartVerifySignatureElement();
+            m_rParser.m_pXSecController->addSignature();
+            if (!ouIdAttr.isEmpty())
+            {
+                m_rParser.m_pXSecController->setId( ouIdAttr );
+            }
         }
-        else if (aName == "loext:SignatureLineValidImage")
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            m_pXSecController->setValidSignatureImage( 
m_ouSignatureLineValidImage );
-            m_bInSignatureLineValidImage = false;
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignedInfo")
+            {
+                return std::make_unique<DsSignedInfoContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureValue")
+            {
+                return std::make_unique<DsSignatureValueContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "KeyInfo")
+            {
+                return std::make_unique<DsKeyInfoContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Object")
+            {
+                return std::make_unique<DsObjectContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-        else if (aName == "loext:SignatureLineInvalidImage")
+};
+
+class XSecParser::DsigSignaturesContext
+    : public XSecParser::Context
+{
+    public:
+        DsigSignaturesContext(XSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : XSecParser::Context(rParser, std::move(pOldNamespaceMap))
         {
-            m_pXSecController->setInvalidSignatureImage( 
m_ouSignatureLineInvalidImage );
-            m_bInSignatureLineInvalidImage = false;
         }
 
-        if (m_xNextHandler.is())
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
         {
-            m_xNextHandler->endElement(aName);
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Signature")
+            {
+                return std::make_unique<DsSignatureContext>(m_rParser, 
std::move(pOldNamespaceMap));
+            }
+            return 
XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), 
nNamespace, rName);
         }
-    }
-    catch (css::uno::Exception& )
-    {//getCaughtException MUST be the first line in the catch block
-        css::uno::Any exc =  cppu::getCaughtException();
-        throw css::xml::sax::SAXException(
-            "xmlsecurity: Exception in XSecParser::endElement",
-            nullptr, exc);
-    }
-    catch (...)
-    {
-        throw css::xml::sax::SAXException(
-            "xmlsecurity: unexpected exception in XSecParser::endElement", 
nullptr,
-            css::uno::Any());
-    }
+};
+
+
+XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper,
+    XSecController* pXSecController)
+    : m_pNamespaceMap(new SvXMLNamespaceMap)
+    , m_pXSecController(pXSecController)
+    , m_bReferenceUnresolved(false)
+    , m_nReferenceDigestID(css::xml::crypto::DigestID::SHA1)
+    , m_rXMLSignatureHelper(rXMLSignatureHelper)
+{
+    using namespace xmloff::token;
+    m_pNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), 
XML_NAMESPACE_XML );
+    m_pNamespaceMap->Add( "_dsig_ooo", GetXMLToken(XML_N_DSIG_OOO), 
XML_NAMESPACE_DSIG_OOO );
+    m_pNamespaceMap->Add( "_dsig", GetXMLToken(XML_N_DSIG), XML_NAMESPACE_DSIG 
);
+    m_pNamespaceMap->Add( "_ds", GetXMLToken(XML_N_DS), XML_NAMESPACE_DS );
+    m_pNamespaceMap->Add( "_xades132", GetXMLToken(XML_N_XADES132), 
XML_NAMESPACE_XADES132);
+    m_pNamespaceMap->Add( "_xades141", GetXMLToken(XML_N_XADES141), 
XML_NAMESPACE_XADES141);
+    m_pNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
+    m_pNamespaceMap->Add( "_office_libo",
+                         GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
 }
 
-void SAL_CALL XSecParser::characters( const OUString& aChars )
+OUString 
XSecParser::HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> 
const& xAttrs)
 {
-    if (m_bInX509IssuerName)
-    {
-        m_ouX509IssuerName += aChars;
-    }
-    else if (m_bInX509SerialNumber)
-    {
-        m_ouX509SerialNumber += aChars;
-    }
-    else if (m_bInX509Certificate)
-    {
-        m_ouX509Certificate += aChars;
-    }
-    else if (m_bInGpgCertificate)
+    OUString ouIdAttr = getIdAttr(xAttrs);
+    if (!ouIdAttr.isEmpty())
     {
-        m_ouGpgCertificate += aChars;
+        m_pXSecController->collectToVerify( ouIdAttr );
     }
-    else if (m_bInGpgKeyID)
+    return ouIdAttr;
+}
+
+OUString XSecParser::getIdAttr(const css::uno::Reference< 
css::xml::sax::XAttributeList >& xAttribs )
+{
+    OUString ouIdAttr = xAttribs->getValueByName("id");
+
+    if (ouIdAttr.isEmpty())
     {
-        m_ouGpgKeyID += aChars;
+        ouIdAttr = xAttribs->getValueByName("Id");
     }
-    else if (m_bInGpgOwner)
+
+    return ouIdAttr;
+}
+
+/*
+ * XDocumentHandler
+ */
+void SAL_CALL XSecParser::startDocument(  )
+{
+    if (m_xNextHandler.is())
     {
-        m_ouGpgOwner += aChars;
+        m_xNextHandler->startDocument();
     }
-    else if (m_bInSignatureValue)
+}
+
+void SAL_CALL XSecParser::endDocument(  )
+{
+    if (m_xNextHandler.is())
     {
-        m_ouSignatureValue += aChars;
+        m_xNextHandler->endDocument();
     }
-    else if (m_bInDigestValue && !m_bInCertDigest)
+}
+
+void SAL_CALL XSecParser::startElement(
+    const OUString& rName,
+    const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
+{
+    assert(m_pNamespaceMap);
+    std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
+        SvXMLImport::processNSAttributes(m_pNamespaceMap, nullptr, xAttribs));
+
+    OUString localName;
+    sal_uInt16 const nPrefix(m_pNamespaceMap->GetKeyByAttrName(rName, 
&localName));
+
+    std::unique_ptr<Context> pContext;
+
+    if (m_ContextStack.empty())
     {
-        m_ouDigestValue += aChars;
+        if ((nPrefix == XML_NAMESPACE_DSIG || nPrefix == 
XML_NAMESPACE_DSIG_OOO)
+            && localName == "document-signatures")
+        {
+            pContext.reset(new DsigSignaturesContext(*this, 
std::move(pRewindMap)));
+        }
+        else
+        {
+            throw css::xml::sax::SAXException(
+                "xmlsecurity: unexpected root element", nullptr,
+                css::uno::Any());
+        }
     }
-    else if (m_bInDate)
+    else
     {
-        m_ouDate += aChars;
+        pContext = m_ContextStack.top()->CreateChildContext(
+                std::move(pRewindMap), nPrefix, localName);
     }
-    else if (m_bInDescription)
+
+    m_ContextStack.push(std::move(pContext));
+    assert(!pRewindMap);
+
+    try
     {
-        m_ouDescription += aChars;
+        m_ContextStack.top()->StartElement(xAttribs);
+
+        if (m_xNextHandler.is())
+        {
+            m_xNextHandler->startElement(rName, xAttribs);
+        }
     }
-    else if (m_bInCertDigest)
-    {
-        m_ouCertDigest += aChars;
+    catch (css::uno::Exception& )
+    {//getCaughtException MUST be the first line in the catch block
+        css::uno::Any exc =  cppu::getCaughtException();
+        throw css::xml::sax::SAXException(
+            "xmlsecurity: Exception in XSecParser::startElement",
+            nullptr, exc);
     }
-    else if (m_bInEncapsulatedX509Certificate)
+    catch (...)
     {
-        m_ouEncapsulatedX509Certificate += aChars;
+        throw css::xml::sax::SAXException(
+            "xmlsecurity: unexpected exception in XSecParser::startElement", 
nullptr,
+            css::uno::Any());
     }
-    else if (m_bInSigningTime)
+}
+
+void SAL_CALL XSecParser::endElement(const OUString& rName)
+{
+    assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+
+    try
     {
-        m_ouDate += aChars;
+        m_ContextStack.top()->EndElement();
+
+        if (m_xNextHandler.is())
+        {
+            m_xNextHandler->endElement(rName);
+        }
     }
-    else if (m_bInSignatureLineId)
-    {
-        m_ouSignatureLineId += aChars;
+    catch (css::uno::Exception& )
+    {//getCaughtException MUST be the first line in the catch block
+        css::uno::Any exc =  cppu::getCaughtException();
+        throw css::xml::sax::SAXException(
+            "xmlsecurity: Exception in XSecParser::endElement",
+            nullptr, exc);
     }
-    else if (m_bInSignatureLineValidImage)
+    catch (...)
     {
-        m_ouSignatureLineValidImage += aChars;
+        throw css::xml::sax::SAXException(
+            "xmlsecurity: unexpected exception in XSecParser::endElement", 
nullptr,
+            css::uno::Any());
     }
-    else if (m_bInSignatureLineInvalidImage)
+
+    if (m_ContextStack.top()->m_pOldNamespaceMap)
     {
-        m_ouSignatureLineInvalidImage += aChars;
+        m_pNamespaceMap = std::move(m_ContextStack.top()->m_pOldNamespaceMap);
     }
+    m_ContextStack.pop();
+}
+
+void SAL_CALL XSecParser::characters(const OUString& rChars)
+{
+    assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+    m_ContextStack.top()->Characters(rChars);
 
     if (m_xNextHandler.is())
     {
-        m_xNextHandler->characters(aChars);
+        m_xNextHandler->characters(rChars);
     }
 }
 
diff --git a/xmlsecurity/source/helper/xsecparser.hxx 
b/xmlsecurity/source/helper/xsecparser.hxx
index d9b079aa3116..33896eff8d10 100644
--- a/xmlsecurity/source/helper/xsecparser.hxx
+++ b/xmlsecurity/source/helper/xsecparser.hxx
@@ -25,6 +25,10 @@
 
 #include <cppuhelper/implbase.hxx>
 
+#include <xmloff/namespacemap.hxx>
+
+#include <stack>
+
 class XMLSignatureHelper;
 class XSecController;
 
@@ -48,7 +52,51 @@ class XSecParser: public cppu::WeakImplHelper
  
******************************************************************************/
 {
     friend class XSecController;
+public:
+    class Context;
 private:
+    class UnknownContext;
+    class LoPGPOwnerContext;
+    class DsPGPKeyPacketContext;
+    class DsPGPKeyIDContext;
+    class DsPGPDataContext;
+    class DsX509CertificateContext;
+    class DsX509SerialNumberContext;
+    class DsX509IssuerNameContext;
+    class DsX509IssuerSerialContext;
+    class DsX509DataContext;
+    class DsKeyInfoContext;
+    class DsSignatureValueContext;
+    class DsDigestValueContext;
+    class DsDigestMethodContext;
+    class DsTransformContext;
+    class DsTransformsContext;
+    class DsReferenceContext;
+    class DsSignatureMethodContext;
+    class DsSignedInfoContext;
+    class XadesEncapsulatedX509CertificateContext;
+    class XadesCertificateValuesContext;
+    class XadesUnsignedSignaturePropertiesContext;
+    class XadesUnsignedPropertiesContext;
+    class LoSignatureLineIdContext;
+    class LoSignatureLineValidImageContext;
+    class LoSignatureLineInvalidImageContext;
+    class LoSignatureLineContext;
+    class XadesCertDigestContext;
+    class XadesCertContext;
+    class XadesSigningCertificateContext;
+    class XadesSigningTimeContext;
+    class XadesSignedSignaturePropertiesContext;
+    class XadesSignedPropertiesContext;
+    class XadesQualifyingPropertiesContext;
+    class DcDateContext;
+    class DcDescriptionContext;
+    class DsSignaturePropertyContext;
+    class DsSignaturePropertiesContext;
+    class DsObjectContext;
+    class DsSignatureContext;
+    class DsigSignaturesContext;
+
     /*
      * the following members are used to reserve the signature information,
      * including X509IssuerName, X509SerialNumber, and X509Certificate,etc.
@@ -70,25 +118,8 @@ private:
     OUString m_ouSignatureLineValidImage;
     OUString m_ouSignatureLineInvalidImage;
 
-    /*
-     * whether inside a particular element
-     */
-    bool m_bInX509IssuerName;
-    bool m_bInX509SerialNumber;
-    bool m_bInX509Certificate;
-    bool m_bInGpgCertificate;
-    bool m_bInGpgKeyID;
-    bool m_bInGpgOwner;
-    bool m_bInCertDigest;
-    bool m_bInEncapsulatedX509Certificate;
-    bool m_bInSigningTime;
-    bool m_bInDigestValue;
-    bool m_bInSignatureValue;
-    bool m_bInDate;
-    bool m_bInDescription;
-    bool m_bInSignatureLineId;
-    bool m_bInSignatureLineValidImage;
-    bool m_bInSignatureLineInvalidImage;
+    std::stack<std::unique_ptr<Context>> m_ContextStack;
+    std::unique_ptr<SvXMLNamespaceMap> m_pNamespaceMap;
 
     /*
      * the XSecController collaborating with XSecParser
@@ -116,7 +147,7 @@ private:
     sal_Int32 m_nReferenceDigestID;
     XMLSignatureHelper& m_rXMLSignatureHelper;
 
-private:
+    OUString HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> 
const& xAttrs);
     static OUString getIdAttr(const css::uno::Reference<
             css::xml::sax::XAttributeList >& xAttribs );
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to