diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-02-12 16:42:51 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2021-03-03 12:43:36 +0100 |
commit | 12b15be8f4f930a04d8056b9219ac969b42a9784 (patch) | |
tree | 4a721e5f805d89fd0eb44a18317f2e775dd50a63 | |
parent | 8a5b110ec48629bbfe58f6e76803f27fe2f69882 (diff) |
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.stahl@allotropia.de>
-rw-r--r-- | include/xmloff/xmlimp.hxx | 6 | ||||
-rw-r--r-- | include/xmloff/xmlnamespace.hxx | 7 | ||||
-rw-r--r-- | include/xmloff/xmltoken.hxx | 13 | ||||
-rw-r--r-- | xmloff/source/core/xmlimp.cxx | 23 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 13 | ||||
-rw-r--r-- | xmloff/source/token/tokens.txt | 10 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecparser.cxx | 1586 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecparser.hxx | 71 |
8 files changed, 1404 insertions, 325 deletions
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,131 +21,437 @@ #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") + { + 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") { - m_pXSecController->setId( ouIdAttr ); + 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"); - if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256 - || ouAlgorithm == ALGO_ECDSASHA512) - m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA); } - else if ( aName == "Reference" ) + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) 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("#")) + 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") { - /* - * remove the first character '#' from the attribute value - */ - m_pXSecController->addReference( ouUri.copy(1), m_nReferenceDigestID, ouType ); + return std::make_unique<DsX509IssuerNameContext>(m_rParser, std::move(pOldNamespaceMap)); } - else + if (nNamespace == XML_NAMESPACE_DS && rName == "X509SerialNumber") { - /* - * remember the uri - */ - m_currentReferenceURI = ouUri; - m_bReferenceUnresolved = true; + 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); } - else if (aName == "DigestMethod") +}; + +class XSecParser::DsX509DataContext + : public XSecParser::Context +{ + public: + DsX509DataContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - OUString ouAlgorithm = xAttribs->getValueByName("Algorithm"); + } + + 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()) @@ -155,342 +461,1034 @@ void SAL_CALL XSecParser::startElement( && ouAlgorithm != ALGO_XMLDSIGSHA512, "xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512"); if (ouAlgorithm == ALGO_XMLDSIGSHA1) - m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1; + m_rParser.m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1; else if (ouAlgorithm == ALGO_XMLDSIGSHA256) - m_nReferenceDigestID = css::xml::crypto::DigestID::SHA256; + m_rParser.m_nReferenceDigestID = css::xml::crypto::DigestID::SHA256; else if (ouAlgorithm == ALGO_XMLDSIGSHA512) - m_nReferenceDigestID = css::xml::crypto::DigestID::SHA512; + m_rParser.m_nReferenceDigestID = css::xml::crypto::DigestID::SHA512; else - m_nReferenceDigestID = 0; + m_rParser.m_nReferenceDigestID = 0; } } - else if (aName == "Transform") +}; + +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_bReferenceUnresolved ) + if (m_rParser.m_bReferenceUnresolved) { - OUString ouAlgorithm = xAttribs->getValueByName("Algorithm"); + OUString ouAlgorithm = xAttrs->getValueByName("Algorithm"); if (ouAlgorithm == ALGO_C14N) /* * a xml stream */ { - m_pXSecController->addStreamReference( m_currentReferenceURI, false, m_nReferenceDigestID ); - m_bReferenceUnresolved = false; + m_rParser.m_pXSecController->addStreamReference( m_rParser.m_currentReferenceURI, false, m_rParser.m_nReferenceDigestID ); + m_rParser.m_bReferenceUnresolved = false; } } } - else if (aName == "X509IssuerName") +}; + +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 { - m_ouX509IssuerName.clear(); - m_bInX509IssuerName = true; + 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 ); } - else if (aName == "X509SerialNumber") + + virtual std::unique_ptr<Context> CreateChildContext( + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, + sal_uInt16 const nNamespace, OUString const& rName) override { - m_ouX509SerialNumber.clear(); - m_bInX509SerialNumber = true; + 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); } - else if (aName == "X509Certificate") +}; + +class XSecParser::DsSignatureMethodContext + : public XSecParser::Context +{ + public: + DsSignatureMethodContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - m_ouX509Certificate.clear(); - m_bInX509Certificate = true; } - else if (aName == "PGPData") + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override { - m_pXSecController->switchGpgSignature(); + OUString ouAlgorithm = xAttrs->getValueByName("Algorithm"); + if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256 + || ouAlgorithm == ALGO_ECDSASHA512) + { + m_rParser.m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA); + } } - else if (aName == "PGPKeyID") +}; + +class XSecParser::DsSignedInfoContext + : public XSecParser::Context +{ + public: + DsSignedInfoContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - m_ouGpgKeyID.clear(); - m_bInGpgKeyID = true; } - else if (aName == "PGPKeyPacket") + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override { - m_ouGpgCertificate.clear(); - m_bInGpgCertificate = true; + 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); } - else if (aName == "loext:PGPOwner") +}; + +class XSecParser::XadesEncapsulatedX509CertificateContext + : public XSecParser::Context +{ + public: + XadesEncapsulatedX509CertificateContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - m_ouGpgOwner.clear(); - m_bInGpgOwner = true; } - else if (aName == "SignatureValue") + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override { - m_ouSignatureValue.clear(); - m_bInSignatureValue = true; + m_rParser.HandleIdAttr(xAttrs); + m_rParser.m_ouEncapsulatedX509Certificate.clear(); } - else if (aName == "DigestValue" && !m_bInCertDigest) + + virtual void EndElement() override { - m_ouDigestValue.clear(); - m_bInDigestValue = true; + m_rParser.m_pXSecController->addEncapsulatedX509Certificate( m_rParser.m_ouEncapsulatedX509Certificate ); } - else if (aName == "xd:CertDigest") + + virtual void Characters(OUString const& rChars) override { - m_ouCertDigest.clear(); - m_bInCertDigest = true; + m_rParser.m_ouEncapsulatedX509Certificate += rChars; } - // 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::XadesCertificateValuesContext + : public XSecParser::Context +{ + public: + XadesCertificateValuesContext(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 == "EncapsulatedX509Certificate") { - m_pXSecController->setPropertyId( ouIdAttr ); + return std::make_unique<XadesEncapsulatedX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap)); } + // missing: xades:OtherCertificate + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); } - else if (aName == "dc:date") +}; + +class XSecParser::XadesUnsignedSignaturePropertiesContext + : public XSecParser::Context +{ + public: + XadesUnsignedSignaturePropertiesContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - if (m_ouDate.isEmpty()) - m_bInDate = true; } - else if (aName == "dc:description") + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override { - m_ouDescription.clear(); - m_bInDescription = true; + m_rParser.HandleIdAttr(xAttrs); } - else if (aName == "loext:SignatureLineId") + + virtual std::unique_ptr<Context> CreateChildContext( + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, + sal_uInt16 const nNamespace, OUString const& rName) override { - m_ouSignatureLineId.clear(); - m_bInSignatureLineId = true; + 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); } - else if (aName == "loext:SignatureLineValidImage") +}; + +class XSecParser::XadesUnsignedPropertiesContext + : public XSecParser::Context +{ + public: + XadesUnsignedPropertiesContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - m_ouSignatureLineValidImage.clear(); - m_bInSignatureLineValidImage = true; } - else if (aName == "loext:SignatureLineInvalidImage") + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override { - m_ouSignatureLineInvalidImage.clear(); - m_bInSignatureLineInvalidImage = true; + m_rParser.HandleIdAttr(xAttrs); } - 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->startElement(aName, xAttribs); + 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); } - } - 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 ) +class XSecParser::LoSignatureLineIdContext + : public XSecParser::Context { - try - { - if (aName == "DigestValue" && !m_bInCertDigest) + public: + LoSignatureLineIdContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - m_bInDigestValue = false; } - else if ( aName == "Reference" ) + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override { - if ( m_bReferenceUnresolved ) - /* - * it must be an octet stream - */ + 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 + { + 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_ouCertDigest); + } + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +}; + +class XSecParser::XadesCertContext + : public XSecParser::Context +{ + public: + XadesCertContext(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_XADES132 && rName == "CertDigest") + { + return std::make_unique<XadesCertDigestContext>(m_rParser, std::move(pOldNamespaceMap)); + } + if (nNamespace == XML_NAMESPACE_XADES132 && rName == "IssuerSerial") + { + return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap)); + } + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +}; + +class XSecParser::XadesSigningCertificateContext + : public XSecParser::Context +{ + public: + XadesSigningCertificateContext(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_XADES132 && rName == "Cert") { - m_pXSecController->addStreamReference( m_currentReferenceURI, true, m_nReferenceDigestID ); - m_bReferenceUnresolved = false; + return std::make_unique<XadesCertContext>(m_rParser, std::move(pOldNamespaceMap)); } + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +}; - m_pXSecController->setDigestValue( m_nReferenceDigestID, m_ouDigestValue ); +class XSecParser::XadesSigningTimeContext + : public XSecParser::Context +{ + public: + XadesSigningTimeContext(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_ouDate.clear(); } - else if ( aName == "SignatureValue" ) + + virtual void EndElement() override { - m_pXSecController->setSignatureValue( m_ouSignatureValue ); - m_bInSignatureValue = false; + m_rParser.m_pXSecController->setDate( m_rParser.m_ouDate ); } - else if (aName == "X509IssuerName") + + virtual void Characters(OUString const& rChars) override { - m_pXSecController->setX509IssuerName( m_ouX509IssuerName ); - m_bInX509IssuerName = false; + m_rParser.m_ouDate += rChars; } - else if (aName == "X509SerialNumber") +}; + +class XSecParser::XadesSignedSignaturePropertiesContext + : public XSecParser::Context +{ + public: + XadesSignedSignaturePropertiesContext(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; + m_rParser.HandleIdAttr(xAttrs); } - 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_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); } - else if (aName == "PGPKeyPacket") +}; + +class XSecParser::XadesSignedPropertiesContext + : public XSecParser::Context +{ + public: + XadesSignedPropertiesContext(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_rParser.HandleIdAttr(xAttrs); + } + + virtual std::unique_ptr<Context> CreateChildContext( + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, + sal_uInt16 const nNamespace, OUString const& rName) override { - m_pXSecController->setGpgOwner( m_ouGpgOwner ); - m_bInGpgOwner = false; + if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedSignatureProperties") + { + return std::make_unique<XadesSignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); + } + // missing: xades:SignedDataObjectProperties + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +}; + +class XSecParser::XadesQualifyingPropertiesContext + : public XSecParser::Context +{ + public: + XadesQualifyingPropertiesContext(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 == "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 == "xd:CertDigest") +}; + +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_pXSecController->setCertDigest( m_ouCertDigest ); - m_bInCertDigest = false; } - else if (aName == "xd:EncapsulatedX509Certificate" || aName == "xades:EncapsulatedX509Certificate") + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override { - m_pXSecController->addEncapsulatedX509Certificate( m_ouEncapsulatedX509Certificate ); - m_bInEncapsulatedX509Certificate = false; + m_isIgnore = !m_rParser.m_ouDate.isEmpty(); } - else if (aName == "xd:SigningTime" || aName == "xades:SigningTime") + + virtual void EndElement() override { - m_pXSecController->setDate( m_ouDate ); - m_bInSigningTime = false; + if (!m_isIgnore) + { + m_rParser.m_pXSecController->setDate( m_rParser.m_ouDate ); + } } - else if (aName == "dc:date") + + virtual void Characters(OUString const& rChars) override { - if (m_bInDate) + if (!m_isIgnore) { - m_pXSecController->setDate( m_ouDate ); - m_bInDate = false; + m_rParser.m_ouDate += rChars; } } - else if (aName == "dc:description") +}; + +class XSecParser::DcDescriptionContext + : public XSecParser::Context +{ + public: + DcDescriptionContext(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; + m_rParser.m_ouDescription.clear(); } - else if (aName == "loext:SignatureLineValidImage") + + virtual void EndElement() override { - m_pXSecController->setValidSignatureImage( m_ouSignatureLineValidImage ); - m_bInSignatureLineValidImage = false; + m_rParser.m_pXSecController->setDescription( m_rParser.m_ouDescription ); } - else if (aName == "loext:SignatureLineInvalidImage") + + virtual void Characters(OUString const& rChars) override { - m_pXSecController->setInvalidSignatureImage( m_ouSignatureLineInvalidImage ); - m_bInSignatureLineInvalidImage = false; + m_rParser.m_ouDescription += rChars; } +}; - if (m_xNextHandler.is()) +class XSecParser::DsSignaturePropertyContext + : public XSecParser::Context +{ + public: + DsSignaturePropertyContext(XSecParser & rParser, + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap) + : XSecParser::Context(rParser, std::move(pOldNamespaceMap)) { - m_xNextHandler->endElement(aName); } - } - 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()); - } + + virtual void StartElement( + css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override + { + OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs)); + if (!ouIdAttr.isEmpty()) + { + m_rParser.m_pXSecController->setPropertyId( ouIdAttr ); + } + } + + virtual std::unique_ptr<Context> CreateChildContext( + std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap, + sal_uInt16 const nNamespace, OUString const& rName) override + { + 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); + } +}; + +class XSecParser::DsSignaturePropertiesContext + : public XSecParser::Context +{ + public: + DsSignaturePropertiesContext(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 == "SignatureProperty") + { + return std::make_unique<DsSignaturePropertyContext>(m_rParser, std::move(pOldNamespaceMap)); + } + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +}; + +class XSecParser::DsObjectContext + : public XSecParser::Context +{ + public: + DsObjectContext(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 == "SignatureProperties") + { + return std::make_unique<DsSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); + } + if (nNamespace == XML_NAMESPACE_XADES132 && rName == "QualifyingProperties") + { + return std::make_unique<XadesQualifyingPropertiesContext>(m_rParser, std::move(pOldNamespaceMap)); + } + // missing: ds:Manifest + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +}; + +class XSecParser::DsSignatureContext + : public XSecParser::Context +{ + public: + DsSignatureContext(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 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 ); + } + } + + 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 == "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); + } +}; + +class XSecParser::DsigSignaturesContext + : public XSecParser::Context +{ + public: + DsigSignaturesContext(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 == "Signature") + { + return std::make_unique<DsSignatureContext>(m_rParser, std::move(pOldNamespaceMap)); + } + return XSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName); + } +}; + + +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) + OUString ouIdAttr = getIdAttr(xAttrs); + if (!ouIdAttr.isEmpty()) { - m_ouX509Certificate += aChars; + m_pXSecController->collectToVerify( ouIdAttr ); } - else if (m_bInGpgCertificate) - { - m_ouGpgCertificate += aChars; - } - 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 ); |